Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [Алгоритм] Ошибка в сортировке


Автор: lansel 16.7.2008, 16:08
Помогите, пожайлуста, разобраться...как сделать чтоб сортировались все элементы? Сейчас сортируется всё кроме первого :(
Код

#include <vcl.h>
#pragma hdrstop
#include "math.h"
#include <stdio.h>
#include <dos.h>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
const n=7;
struct zap
{
int key;
};
zap X[n];

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
 int busort (zap X[])
 {
  int i,j,k,m,n1; zap w,v;
  int path[20];
  {
    n1=n-1;
   for (m=n1/2;m>=1;m--)
   {  i=0; j=m; path[i]=j;
   i++;
    while (2*j<n1) {
                   if (X[2*j+1].key<X[2*j].key)
                      {
                        j=j*2; path[i]=j; i++;
                      }
                 else {
                       j=j*2+1; path[i]=j; i++;
                      }
                    }
    if (2*j==n1) { j=n1; path[i]=j; i++;}
    i=m;
    while ((j>i)&& (X[j].key<X[i].key))
    {j=j/2;}
    i=m; v=X[path[0]]; k=0;
    while (path[k]<j)
    {X[path[k]]=X[path[k+1]];
     k++;}
    X[path[k]]=v;
   }
   for (m=n1;m>=2;m--)
   {
   w=X[1]; X[1]=X[m]; X[m]=w;
   if (m!=2)
   { i=0;j=1; path[i]=j; i++;
      while ((2*j)<(m-1)){
                      if (X[2*j+1].key < X[2*j].key)
                      {j=j*2; path[i]=j; i++;}
                      else {j=j*2+1; path[i]=j; i++;}
                      }
     if ((2*j)==(m-1)){j=m-1; path[i]=j; i++;}
     i=1;
     while((j>i)&& (X[j].key<X[i].key)){j=j/2;}
     i=1; v=X[path[0]]; k=0;
     while (path[k]<j){X[path[k]]=X[path[k+1]]; k++;}
     X[path[k]]=v;
   }
   }
  }
 }
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  int j,k,i;
  {
{
X[0].key=10;
X[1].key=55;
X[2].key=8;
X[3].key=99;
X[4].key=9;
X[5].key=3;
X[6].key=1;
 busort(X);
 }
   
  for (k=0;k<n;k++)
  Form1->Memo1->Lines->Add(IntToStr(X[k].key)) ;
}
}

Автор: HoTMetaL 16.7.2008, 21:51
lansel, у меня к тебе несколько вопросов:
1) Чё это за алгоритм и где ты его взял?
2) Ты умеешь пользоваться трассировкой в Билдере? - если нет - читай учебники.
3) Ты не пробовал САМ ручками прогнать эту прогу на бумажке?

Добавлено через 1 минуту и 57 секунд
PS Написание кода ужасное! После каждой точки с запятой (;) переходи на новую строку.

Добавлено через 2 минуты и 48 секунд
И научись правильно использовать отступы.

Автор: lansel 17.7.2008, 09:17
Цитата(HoTMetaL @ 16.7.2008,  21:51)
lansel, у меня к тебе несколько вопросов:
1) Чё это за алгоритм и где ты его взял?
2) Ты умеешь пользоваться трассировкой в Билдере? - если нет - читай учебники.
3) Ты не пробовал САМ ручками прогнать эту прогу на бумажке?

Добавлено @ 21:53
PS Написание кода ужасное! После каждой точки с запятой (;) переходи на новую строку.

Добавлено @ 21:54
И научись правильно использовать отступы.

1) Ну это длинная история....есть немецкий ученный который заниматься сортировками, вот в одной из его статей был взят алгоритм, немного улучшен...и дан мне...
2)Не общайся со мной как с маленьким мальчиком: 
    а) я девушка!!! 
    б) умею пользоваться трассировкой!!!
3) пробовала, и не только я!

Ну зачем же так придираться к коду!!
Код какой он есть и я его не выбирала smile

Я же прошу помощи, а не критики.

Автор: HoTMetaL 17.7.2008, 09:50
Цитата(lansel @  17.7.2008,  09:17 Найти цитируемый пост)
3) пробовала, и не только я!


Ну и где результаты? Если программа была прогнана ручками, то ошибка выявляется сразу. По опыту скажу - в различных алгоритмах обработки массивов косяки часто появляются из-за неправильного использования условий строго и нестрого неравенства (<,>,<=,>=), а так же не правильного условия выхода из цикла (до n, до n+1 ?)

Можно словесное описание алгоритма?

PS 
Цитата(lansel @  17.7.2008,  09:17 Найти цитируемый пост)
а) я девушка!!! 


А я парень ;-)

Автор: lansel 17.7.2008, 10:05
Цитата(HoTMetaL @ 17.7.2008,  09:50)


Описания алгоритма, к сожелению, нет :(
Все что есть это не рабочие реалиации на Билдере и Делфи :(

Автор: Rodman 17.7.2008, 10:14
Цитата(lansel @  16.7.2008,  16:08 Найти цитируемый пост)
   for (m=n1;m>=2;m--)
   {
   w=X[1]; X[1]=X[m]; X[m]=w;

сильно не вникал в код, но эти две строчки меня беспокоят...

и второе: lansel сформулируй плиз задание...
на мой взгляд в коде много лишнего (подозреваю что из-за неопытности)... но помочь возможно только при помощи нормально поставленной задачи...


M
Rodman
Прекращайте ругаться...

Автор: lansel 17.7.2008, 10:25
Цитата(Rodman @ 17.7.2008,  10:14)
lansel сформулируй плиз задание...

Эээ..если у меня преподаватель не опытен...но чему я тогда вообще учусь?!

Задача поставлена, нужно чтоб сортировались правильно все элемены.

Или вам нужнен точный алгоритм?

Автор: Rodman 17.7.2008, 10:31
Цитата(lansel @  17.7.2008,  10:25 Найти цитируемый пост)
Или вам нужнен точный алгоритм? 
нужен как воздух...
Цитата(lansel @  17.7.2008,  10:25 Найти цитируемый пост)
Задача поставлена, нужно чтоб сортировались правильно все элемены.
ну или попробуй самостоятельно сформулировать...

у тебя есть массив и тебе надо отсортировать элементы... массив одномерный? какой метод сортировки? как вводится массив? куда выводится? какие еще доп. условия есть?

ждемс

Автор: lansel 17.7.2008, 10:39
Цитата(Rodman @ 17.7.2008,  10:31)
у тебя есть массив и тебе надо отсортировать элементы... массив одномерный? какой метод сортировки? как вводится массив? куда выводится? какие еще доп. условия есть?

ждемс

Массив одномернный.
Это пирамидальная сортировка, возможно слабая.
Массив рандомный должен быть, элементы будет доходить до миллиона. Куда будет выводиться, да без разницы...мне главное время за которое он отсортирует smile, а потом различные числа сравнения и обмена.

Автор: Rodman 17.7.2008, 10:59
Взял http://www.bib.com.ua/info1837.html

судя по твоим пунктам - то что тебе надо (см. атач)!

Автор: lansel 17.7.2008, 16:26
Цитата(Rodman @ 17.7.2008,  10:59)
Взял http://www.bib.com.ua/info1837.html

судя по твоим пунктам - то что тебе надо (см. атач)!

Ну я так и думала, скажи вам алгоритм дадите что-то подобное готовое! Этого алгоритма готового нет в рунете!!!

Точто вы прислали я с этим алгоритмом знакома smile спасибо, но он мне не нужен.

Автор: Rodman 17.7.2008, 16:30
ну на сколько я понял, он устраивает всем твоим требованиям...

Автор: lansel 17.7.2008, 16:50
Цитата(Rodman @ 17.7.2008,  16:30)
ну на сколько я понял, он устраивает всем твоим требованиям...

Да я понимаю....но мне нужен мой....
Пирамидальных сортировок большая куча.....я по ним бакалавр защитила.

Автор: THandle 17.7.2008, 23:30
Цитата(lansel @  17.7.2008,  11:05 Найти цитируемый пост)
Все что есть это не рабочие реалиации на Билдере и Делфи :( 


Можно посмотреть реализацию на Делфи? У меня Билдера нет, да и в С++ я не особо силен. А делфийский код мог бы посмотреть, попробовать сделать а потом сравнить с С++...

Автор: lansel 18.7.2008, 10:45
Цитата(THandle @ 17.7.2008,  23:30)
Цитата(lansel @  17.7.2008,  11:05 Найти цитируемый пост)
Все что есть это не рабочие реалиации на Билдере и Делфи :( 


Можно посмотреть реализацию на Делфи? У меня Билдера нет, да и в С++ я не особо силен. А делфийский код мог бы посмотреть, попробовать сделать а потом сравнить с С++...

Код

Procedure busort(var x:array of tip);
var  i,j,k,m,n:integer;w,v:tip;
    path:array[0..40] of integer;
begin
 n:=high(x);
 for m:=n div 2 downto 1 do
  begin
    i:=0; j:=m;    path[i]:=j; inc(i);
    while 2*j < n do
      begin if x[2*j+1].key<x[2*j].key then
             begin  j:=j*2; path[i]:=j; inc(i) end
            else begin j:=j*2+1; path[i]:=j; inc(i)end;
      end;
    if 2*j=n then begin    j:=n; path[i]:=j; inc(i)end;
    i:=m;
    while (j>i) and (x[j].key < x[i].key)do j:=j div 2;
    i:=m; v:=x[path[0]]; k:=0;
    while path[k]<j do begin x[path[k]]:=x[path[k+1]]; inc(k)end;
    x[path[k]]:=v;
  end;
 for m:=n downto 2 do
  begin
   w:=x[1]; x[1]:=x[m]; x[m]:=w;
   if m<>2 then
     begin i:=0; j:=1; path[i]:=j; inc(i);
      while 2*j < m-1 do
       begin if x[2*j+1].key < x[2*j].key then
              begin j:=j*2; path[i]:=j; inc(i) end
             else begin j:=j*2+1; path[i]:=j; inc(i) end;
       end;
      if 2*j= m-1 then begin j:=m-1; path[i]:=j; inc(i)    end;
      i:=1;
      while (j>i) and (x[j].key<x[i].key) do j:=j div 2;
      i:=1;  v:=x[path[0]];  k:=0;
      while path[k] < j do begin x[path[k]]:=x[path[k+1]]; inc(k)end;
      x[path[k]]:=v;
     end;
  end;
end;
procedure TForm1.Button19Click(Sender: TObject);
 VAr i,j:integer; t:cardinal;
begin
Randomize; zz:=0; z:=0; t:=GetTickCount;
 For i:= 1 to m do
 begin For j:=1 to n do X[j].key:= Random(100000000);
 BuSort(X)
 end;
 Memo1.text:=IntToStr(z)+'  '+ IntToStr(zz)+'  '+ FloatToStr(GetTickCount-t)
+'  '+ FloatToStr(n*(ln(n)/Ln(2))+0.41*n)
end;



Автор: THandle 18.7.2008, 11:17
Привел код в относительно красивое состояние(вдруг кто-то захочет подебажить?):

Код

Procedure busort(var x : array of tip);
var  
  i, j, k, m, n : integer;
  w, v : tip;
  path : array [0..40] of integer;
begin
  n := high(x);
  for m := n div 2 downto 1 do
    begin
      i := 0;
      j := m;
      path[i] := j;
      inc(i);
      while 2 * j < n do
        begin 
          if x[2 * j + 1].key < x[2 * j].key then
            begin  
              j := j * 2; 
              path[i] := j; 
              inc(i) 
            end
          else 
            begin 
              j := j * 2 + 1;
              path[i] := j;
              inc(i)
            end;
        end;
      if 2 * j = n then
        begin    
          j := n;
          path[i] := j;
          inc(i)
        end;
      i := m;
      while (j>i) and (x[j].key < x[i].key) do
        j := j div 2;
      i := m; 
      v := x[path[0]]; 
      k := 0;
      while path[k] < j do 
        begin 
          x[path[k]] := x[path[k + 1]];
          inc(k)
        end;
      x[path[k]]:=v;
    end;
  for m := n downto 2 do
    begin
      w := x[1];
      x[1] := x[m];
      x[m] := w;
      if m <> 2 then
        begin 
          i := 0;
          j := 1;
          path[i] := j;
          inc(i);
          while 2 * j < m - 1 do
            begin 
              if x[2 * j + 1].key < x[2*j].key then
                begin 
                  j := j * 2;
                  path[i] := j;
                  inc(i)
                end
              else 
                begin 
                  j := j * 2 + 1;
                  path[i] := j;
                  inc(i) 
                end;
            end;
          if 2 * j = m - 1 then
            begin 
              j := m - 1;
              path[i] := j;
              inc(i)    
            end;
          i := 1;
          while (j>i) and (x[j].key<x[i].key) do 
            j := j div 2;
          i := 1;
          v := x[path[0]];
          k:=0;
          while path[k] < j do 
            begin 
              x[path[k]] := x[path[k+1]];
              inc(k)
            end;
          x[path[k]] := v;
        end;
    end;
end;


Сам постараюсь заняться этим кодом завтра. Сейчас просто день рождения праздную smile 

Кстати, хотелось бы узнать - что это за типчик такой подозрительный в процедурку заходит?

Procedure busort(var x : array of tip);

???

Автор: lansel 18.7.2008, 19:15
Цитата(THandle @ 18.7.2008,  11:17)
Procedure busort(var x : array of tip);

Type tipkey=integer; tip=Record key:tipkey; end;
 Var X:Array[1..n]of tip; 

Автор: Palladin 19.7.2008, 02:47
Неужели для задачи необходимо использовать именно этот код? да и именно этот способ сортировки? 
P.S. Задачу в студию smile 

Автор: lansel 19.7.2008, 09:25
Цитата(Palladin @ 19.7.2008,  02:47)
Неужели для задачи необходимо использовать именно этот код? да и именно этот способ сортировки? 
P.S. Задачу в студию smile

Какую такую задачу??

Да мне нужен именно этот код!!! smile 

Автор: HoTMetaL 19.7.2008, 12:15
Посмотрел я твой код и заодним привёл в порядок. Скажу тебе одну вещь - этот код был написан по алгоритму, в котором нумерация элементов входного массива начиналась с 1, а не с 0. Тебе никто не мешает начинать заполнение массива с первого, а не с нулевого элемента. Пусть он там себе в памяти болтается и никому не мешает.

И ещё, если вдруг кто-то захочет переписать эту программу под массив с нумерацией с нуля, пусть обратит внимание на изменение значений переменной j, т.к. именно она отвечает за индексы.

Код

#include <vcl.h>
#pragma hdrstop
#include "math.h"
#include <stdio.h>
#include <dos.h>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
const n=7;

struct zap{
       int key;
};
zap X[n];

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
int busort (zap X[])
{
    int i,j,k,m,n1;

    int path[20];
    zap w,v;
    
    n1=n-1;
    for(m=n1/2;m>0;m--){
       i=0;
       j=m;
       path[i]=j;
       i++;
       while(2*j<n1){
            if(X[2*j+1].key<X[2*j].key){
              j=j*2;
              path[i]=j;
              i++;
            }else{
              j=j*2+1;
              path[i]=j;
              i++;
            }
       }

       if(2*j==n1){
         j=n1;
         path[i]=j;
         i++;
       }
       i=m;

       while((j>i)&& (X[j].key<X[i].key)){
             j=j/2;
       }

       i=m;
       v=X[path[0]];
       k=0;

       while(path[k]<j){
            X[path[k]]=X[path[k+1]];
            k++;
       }
       X[path[k]]=v;
    }

    for(m=n1;m>=2;m--){
       w=X[1];
       X[1]=X[m];
       X[m]=w;

       if(m!=2){
         i=0;
         j=1;
         path[i]=j;
         i++;

         while((2*j)<(m-1)){
              if(X[2*j+1].key < X[2*j].key){
                j=j*2;
                path[i]=j;
                i++;
              }else{
                j=j*2+1;
                path[i]=j;
                i++;
              }
         }
         if((2*j)==(m-1)){
           j=m-1;
           path[i]=j;
           i++;
         }

         i=1;

         while((j>i)&& (X[j].key<X[i].key)){
              j=j/2;
         }

         i=1;
         v=X[path[0]];
         k=0;

         while(path[k]<j){
              X[path[k]]=X[path[k+1]];
              k++;
         }
         X[path[k]]=v;
       }
    }
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
     int j,k,i;

     X[0].key=100;
     X[1].key=55;
     X[2].key=8;
     X[3].key=99;
     X[4].key=9;
     X[5].key=3;
     X[6].key=1;
     busort(X);

     for(k=0;k<n;k++)
        Form1->Memo1->Lines->Add(IntToStr(X[k].key)) ;

}


Добавлено через 5 минут и 15 секунд
А на Delphi ещё проще: пишешь

Код

X: array [1..N] of integer;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)