IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным. В описании темы указываем язык!!!

> проблема с сортировкой, c++
Rocket
сообщение 1.03.2009 21:05
Сообщение #1


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


Возникла проблема с сортировкой, суть которой заключается в следующем:
допустим, наш изначальный массив 3 7 4 1 8 3 3 5 9 1. Строится бинарное дерево, на следующий уровень идут
3 1 3 3 1, то есть соседние числа сравниваются, дальше идет наименьший элемент.
Следующие уровни: 1 3 1,
1 1
1
В конце остаётся 1, она отправляется в отсортированный массив (в данном случае на первое место), а из начального массива отбрасывается (заменяется на бесконечность).
Вобщем, в этом суть, преподаватель назвал его "турнирной" сортировкой, но это явно не "пирамидальная-турнирная-HeapSort" сортировка, преведённая на форуме.
Вот мой код:

#include <iostream>
#include<conio.h>
#include <windows.h>
#include <math.h>
using namespace std;

int xe; 
int temp[1000], buff[1000];

int stTwo(int size)
{
  int k=0;
  while (pow(2,k)<size)
   k+=1;
   return k;
}


void TurnirSort(int *a, long size, int st, int li)
{ 
    int cl = size;
    int S = li;
    for (int i=0; i<S; i++)
     buff[i]=a[i];
         
  while(cl != 1)
  {
           
  for (int i=0,j=0;i<cl; i+=2,j++)
  {
     if (buff[i]>buff[i+1])
        temp[j]=buff[i+1];
        else temp[j]=buff[i];
  }
  cl = li/2;
  li = cl;
  
  for (int i=0; i<cl; i++)
   buff[i]=temp[i];
   
  for (int i=0; i<cl; i++)
   if(buff[i] == 0) buff[i] = 1000; 
   
  
   }
     
    xe = temp[0];
   
    
    for (int i=0; i<size;i++) 
    if (a[i] == xe) 
    {
         a[i] = 1000;
         break;
    }
        
        
 
     }
     


int main()
{   
    srand(time(NULL));
    int ch,size,l, h, st, li;
    
    cout<<"Please, enter the size of massive to sort!"<<endl;   
    cin>>size;
    cout<<"Please, enter the down border!"<<endl;
    cin>>l;
    cout<<"Please, enter the up border!"<<endl;
    cin>>h;
    
    int a[size]; 
    int vec_sort[size];
     
     st = stTwo(size);
     li = (int)pow(2,st);
     
     
     for(int i=0;i<size;i++)
     {
     a[i]=l+rand()%(h-l); 
     }  
     for (int i=size; i<li;i++)
     {
      a[i] = 1000;   
         }
                      
     for(int i=0;i<size;i++)
     {
     cout<<a[i]<<" ";
     }
     cout << endl << endl;
     
     
     
     long time = GetTickCount();
     
     for(int i=0; i<size; i++)
     {
     TurnirSort(a,size,st,li);
     vec_sort[i] = xe;
     }
     time = GetTickCount()-time; 
     
     for(int i=0;i<size;i++)
     {
     cout<<vec_sort[i]<<" ";
     }
     cout << endl << endl;
     getch();
     cout<<"time = "<<time<<endl;
     getch();
     
}


Тестировал я её на масивах в 10 элементов, всё четко работало и работает, а вот, когда перешёл к практике(массив в 100 элементов), возникла ошибка - тупо выкидывает из программы... в чём проблема?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов(1 - 18)
volvo
сообщение 1.03.2009 21:17
Сообщение #2


Гость






Цитата
в чём проблема?
В вылете за пределы массива... Вот тут:

// Чему здесь равно li? А сколько элементов в массиве A?
     for (int i=size; i<li;i++)
     {
     a[i] = 1000;   
     }


У тебя и при 10 элементах тоже такой же выход за пределы массива, так что не обольщайся, оно и там не работает корректно. smile.gif
 К началу страницы 
+ Ответить 
Rocket
сообщение 1.03.2009 22:06
Сообщение #3


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


Цитата(volvo @ 1.03.2009 21:17) *

В вылете за пределы массива... Вот тут:

// Чему здесь равно li? А сколько элементов в массиве A?
     for (int i=size; i<li;i++)
     {
     a[i] = 1000;   
     }


У тебя и при 10 элементах тоже такой же выход за пределы массива, так что не обольщайся, оно и там не работает корректно. smile.gif

Так-с, исправил эту ошибку. Большое спасибо, volvo smile.gif У этой сортировки есть какое-нибудь нормальное название?)

И ещё, тут нужно график построить (просто до этого момента не сталкивался с графикой в c++).
На одной оси кол-во элементов(допустим 100, 200, 300, 400, 800...), а на другой соответсвенно время...
?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 1.03.2009 22:46
Сообщение #4


Гость






Цитата
У этой сортировки есть какое-нибудь нормальное название?)
Может и есть... По мне - так оно и не надо. Очень уж она неоптимальная, посмотри, сколько раз будет бегать по массиву, чтоб его отсортировать.

Цитата
И ещё, тут нужно график построить (просто до этого момента не сталкивался с графикой в c++).
Графика не определена Стандартом С++, так что это компиляторо- и ОСе- зависимо. Называй свой компилятор, ОС, будем думать что можно сделать...

А может, гистограммы хватит? Или тебе именно график хочется?
 К началу страницы 
+ Ответить 
Rocket
сообщение 1.03.2009 23:14
Сообщение #5


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


Цитата(volvo @ 1.03.2009 22:46) *

Может и есть... По мне - так оно и не надо. Очень уж она неоптимальная, посмотри, сколько раз будет бегать по массиву, чтоб его отсортировать.

Графика не определена Стандартом С++, так что это компиляторо- и ОСе- зависимо. Называй свой компилятор, ОС, будем думать что можно сделать...

А может, гистограммы хватит? Или тебе именно график хочется?

в принципе, гистограмма подойдет, нужно посмотреть на конкретном примере как выглядеть будет...
А для графика (всё равно пригодится): ос - windows xp, пользуюсь Dev- C++, как тут компилятор узнать?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 2.03.2009 0:03
Сообщение #6


Гость






Цитата
пользуюсь Dev- C++, как тут компилятор узнать?
С большой степенью вероятности - GCC, у меня тоже он же, только через Code::Blocks... Можно попробовать использовать Borland BGI Graphics emulation , я уже как-то давал эту ссылку здесь, на этом форуме, вроде сказали, что работает.

А гистограмма.... Ну, вот так:
int main() {
    
    srand(time(NULL));
    int ch,size,l, h, st, li;

    cout<<"Please, enter the down border!"<<endl;
    cin>>l;
    cout<<"Please, enter the up border!"<<endl;
    cin>>h;

    int a[4000];
    int vec_sort[4000];

    int sizes[5] = {100, 200, 300, 400, 800};
    long times[5] = {0};

    for(int sz = 0; sz < 5; sz++) {
        size = sizes[sz];

        st = stTwo(size);
        li = (int)pow(2,st);

        for(int i=0;i<size;i++) {
            a[i]=l+rand()%(h-l);
        }
        cout << "st = " << st << " li = " << li << endl;
        for (int i=size; i<li;i++) {
            a[i] = 1000;
        }
        for(int i=0;i<size;i++) {
            cout<<a[i]<<" ";
        }
        cout << endl << endl;

        long time = GetTickCount();
        
        for(int i=0; i<size; i++) {
            TurnirSort(a,size,st,li);
            vec_sort[i] = xe;
        }
        time = GetTickCount()-time;
        times[sz] = time;

        for(int i=0;i<size;i++) {
            cout<<vec_sort[i]<<" ";
        }
    }

    long max = times[0];
    for(int i = 0; i < 5; i++) {
        max = (times[i] > max) ? times[i] : max;
    }
    for(int i = 0; i < 5; i++) {
        cout << sizes[i] << "|";
        for(int j = 0; j < times[i] * 70. / max; j++) {
            cout << "*";
        }
        cout << endl;
    }
    return 0;
}
(не стал заморачиваться с динамическим выделением памяти, сделал просто очень большой массив, которого заведомо хватит), хотя очень может быть, что при быстром компьютере все times будут нулевыми, и получишь проблему при делении на 0. Тогда придется искать более точный способ засечь время...
 К началу страницы 
+ Ответить 
Rocket
сообщение 2.03.2009 1:02
Сообщение #7


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


Цитата(volvo @ 2.03.2009 0:03) *
очень может быть, что при быстром компьютере все times будут нулевыми, и получишь проблему при делении на 0. Тогда придется искать более точный способ засечь время...
Да, компьютер оказался быстрым - увеличил число элементов в 10 раз. А гистограмма очень хорошо смотрится, думаю подойдёт) ещё раз спасибо! good.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Rocket
сообщение 16.03.2009 23:26
Сообщение #8


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


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

#include <iostream>
#include<conio.h>
#include <windows.h>
#include <math.h>
using namespace std;

int xe;
int stTwo(int size)
{
  int k=0;
  while (pow(2,k)<size)
   k+=1;
   return k;
}

void ToShow(int *a, int size)
{
     for (int i=0; i<size; i++)
     {
         if (a[i] == 1000)
          cout<<"**";
         else cout<<a[i]<<" ";
         }
     cout<<endl;
     }

void TurnirSort(int *a, long size, int st, int li)
{ 
    int buff[li], temp[li];
    int cl = size;
    int S = li;
    for (int i=0; i<S; i++)
     buff[i]=a[i];
         
  while(cl != 1)
  {
           
  for (int i=0,j=0;i<cl; i+=2,j++)
  {
     if (buff[i]>buff[i+1])
        temp[j]=buff[i+1];
        else temp[j]=buff[i];
  }
  cl = li/2;
  li = cl;
  
  for (int i=0; i<cl; i++)
   buff[i]=temp[i];
   
  for (int i=0; i<cl; i++)
   if(buff[i] == 0) buff[i] = 1000; 
   
   }     
   
   ToShow(buff, cl); // промежуточный массив
   
   cout<<endl;
    xe = temp[0];
   
    
    for (int i=0; i<size;i++) 
    if (a[i] == xe) 
    {
         a[i] = 1000;
         break;
    }
    
     }
     
int main()
{   
    srand(time(NULL));
    int ch,size,l, h, st, li;
    
    cout<<"Please, enter the down border!"<<endl;
    cin>>l;
    cout<<"Please, enter the up border!"<<endl;
    cin>>h;
     
     int sizes[5] = {10, 20, 30, 40, 80};
     long times[5] = {0};
     
      for(int sz = 0; sz < 1; sz++)
       {
        size = sizes[sz];
     
     st = stTwo(size);
     li = (int)pow(2,st);
     
     int a[li]; 
     int vec_sort[li];
     
     for(int i=0;i<size;i++)
     {
     a[i]=l+rand()%(h-l); 
     }  
     ToShow(a,size) ; //начальный
     cout<<endl;
  
     
     for (int i=size; i<li;i++)
     {
      a[i] = 1000;   
         }
   
      cout<<endl;   
    long time = GetTickCount();
     
     for(int i=0; i<size; i++)
     {
     TurnirSort(a,size,st,li);
     vec_sort[i] = xe;

     }
     time = GetTickCount()-time; 
     times[sz] = time;
     
     ToShow(vec_sort,size); // отсортированный
     
     cout<<endl;
    
     }
     cout<<endl;
     long max = times[0];
    for(int i = 0; i < 5; i++) {
        max = (times[i] > max) ? times[i] : max;
    }
    for(int i = 0; i < 5; i++) {
        cout << sizes[i] << "|";
        for(int j = 0; j < times[i] * 70. / max; j++) {
            cout << "*";
        }
        
        cout<<endl;
    }
    cout<<endl;
    cout<<" -------"<<"-"<<"-------"<<endl;
    cout<<" Sizes  "<<"|"<<"  Times"<<endl;
    cout<<" -------"<< "-"<<"-------"<<endl;
    for (int i=0; i<5; i++)
    {
        cout<<" "<<sizes[i]<<"   |  "<<times[i]<<endl;
        cout<<" -------"<< "-"<<"-------"<<endl; 
        }
    cout<<endl;
    
     getch();    
}


Но на экран выводятся совершенно не понятные значения... В чем ошибка?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 17.03.2009 0:32
Сообщение #9


Гость






Цитата
Но на экран выводятся совершенно не понятные значения
Чего ж непонятные? Все понятно... Что просил - то и выводится... Смотри:

Цитата
Please, enter the down border!
10
Please, enter the up border!
100
31 20 81 69 42 89 42 45 24 89 // Это - начальный массив


20

24

31

42

42

45

69

81

89

89

20 24 31 42 42 45 69 81 89 89 // Это - отсортированный


10|
20|
30|
40|
80|
между начальным и сортированным - промежуточные, только не массивы, а числа... Потому что CL = 1 все время, и печатается только первый элемента массива.
 К началу страницы 
+ Ответить 
Rocket
сообщение 17.03.2009 11:15
Сообщение #10


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


Цитата(volvo @ 17.03.2009 0:32) *

Чего ж непонятные? Все понятно... Что просил - то и выводится... Смотри:

между начальным и сортированным - промежуточные, только не массивы, а числа... Потому что CL = 1 все время, и печатается только первый элемента массива.

Так вот и засада же, что результаты выводятся корректно, допустим при первом запуске, а потом начинают появляться какие-то громадные значения с минусом. Я скриншот добавил.
Расположил функцию в нужных местах...

#include <iostream>
#include<conio.h>
#include <windows.h>
#include <math.h>
using namespace std;

int xe;
int stTwo(int size)
{
  int k=0;
  while (pow(2,k)<size)
   k+=1;
   return k;
}

void ToShow(int *a, int size)
{
     for (int i=0; i<size; i++)
     {
         if (a[i] == 1000)
          cout<<" * ";
         else cout<<a[i]<<"  ";
         }
     cout<<endl;
     }

void TurnirSort(int *a, long size, int st, int li)
{ 
    int buff[li], temp[li];
    int cl = size;
    int S = li;
    for (int i=0; i<S; i++)
     buff[i]=a[i];
         
  while(cl != 1)
  {
           
  for (int i=0,j=0;i<cl; i+=2,j++)
  {
     if (buff[i]>buff[i+1])
        temp[j]=buff[i+1];
        else temp[j]=buff[i];
  }
  cl = li/2;
  li = cl;
  
  for (int i=0; i<cl; i++)
   buff[i]=temp[i];
   
  for (int i=0; i<cl; i++)
   if(buff[i] == 0) buff[i] = 1000; 
  
  ToShow(buff, cl); // промежуточные массивы
   
   }     
   
   cout<<endl;
    xe = temp[0];
   
    
    for (int i=0; i<size;i++) 
    if (a[i] == xe) 
    {
         a[i] = 1000;
         break;
    }
    
    ToShow(a,size); // измененный массив
    cout<<endl;
    
     }
     
int main()
{   
    srand(time(NULL));
    int ch,size,l, h, st, li;
    
    cout<<"Please, enter the down border!"<<endl;
    cin>>l;
    cout<<"Please, enter the up border!"<<endl;
    cin>>h;
     
     int sizes[5] = {10, 20, 30, 40, 80};
     long times[5] = {0};
     
      for(int sz = 0; sz < 1; sz++)
       {
        size = sizes[sz];
     
     st = stTwo(size);
     li = (int)pow(2,st);
     
     int a[li]; 
     int vec_sort[li];
     
     for(int i=0;i<size;i++)
     {
     a[i]=l+rand()%(h-l); 
     }  
     ToShow(a,size) ; // начальный массив
     cout<<endl;
  
     
     for (int i=size; i<li;i++)
     {
      a[i] = 1000;   
         }
   
      cout<<endl;   
    long time = GetTickCount();
     
     for(int i=0; i<size; i++)
     {
     TurnirSort(a,size,st,li);
     vec_sort[i] = xe;

     }
     time = GetTickCount()-time; 
     times[sz] = time;
     
     ToShow(vec_sort,size); // отсорторованный массив
     
     cout<<endl;
    
     }
     cout<<endl;
     long max = times[0];
    for(int i = 0; i < 5; i++) {
        max = (times[i] > max) ? times[i] : max;
    }
    for(int i = 0; i < 5; i++) {
        cout << sizes[i] << "|";
        for(int j = 0; j < times[i] * 70. / max; j++) {
            cout << "*";
        }
        
        cout<<endl;
    }
    cout<<endl;
    cout<<" -------"<<"-"<<"-------"<<endl;
    cout<<" Sizes  "<<"|"<<"  Times"<<endl;
    cout<<" -------"<< "-"<<"-------"<<endl;
    for (int i=0; i<5; i++)
    {
        cout<<" "<<sizes[i]<<"   |  "<<times[i]<<endl;
        cout<<" -------"<< "-"<<"-------"<<endl; 
        }
    cout<<endl;
    
     getch();    
}




Эскизы прикрепленных изображений
Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 17.03.2009 11:27
Сообщение #11


Гость






Ага... Ты массив buff инициализируешь некорректно... Смотри, что происходит:
Цитата
    for (int i=0; i<S; i++)
     buff[i]=a[i];
, а между тем S больше чем size, кстати... У тебя - вылет за пределы массива a, но ты этого не видишь... Правильно - инициализировать так:
    for (int i=0; i<S; i++) {
        buff[i] = (i < size) ? a[i] : 0;
    }
(для всех индексов, меньших, чем size, копировать элементы из массива a, остальные обнулять)...
 К началу страницы 
+ Ответить 
Rocket
сообщение 17.03.2009 23:03
Сообщение #12


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


Цитата(volvo @ 17.03.2009 11:27) *

Ага... Ты массив buff инициализируешь некорректно... Смотри, что происходит:
, а между тем S больше чем size, кстати... У тебя - вылет за пределы массива a, но ты этого не видишь... Правильно - инициализировать так:
    for (int i=0; i<S; i++) {
        buff[i] = (i < size) ? a[i] : 0;
    }
(для всех индексов, меньших, чем size, копировать элементы из массива a, остальные обнулять)...

Добавил инициализацию:


#include <iostream>
#include<conio.h>
#include <windows.h>
#include <math.h>
using namespace std;

int xe;
int stTwo(int size)
{
  int k=0;
  while (pow(2,k)<size)
   k+=1;
   return k;
}

void ToShow(int *a, int size)
{
     for (int i=0; i<size; i++)
     {
         if (a[i] == 1000)
          cout<<" * ";
         else cout<<a[i]<<"  ";
         }
     cout<<endl;
     }

void TurnirSort(int *a, long size, int st, int li)
{ 
    int buff[li], temp[li];
    int cl = size;
    int S = li;
    int sz = size;
    
    for (int i=0; i<S; i++)
    {
        buff[i] = (i < size) ? a[i] : 0;
    }
            
  while(cl != 1)
  {
           
  for (int i=0,j=0;i<cl; i+=2,j++)
  {
     if (buff[i]>buff[i+1])
        temp[j]=buff[i+1];
        else temp[j]=buff[i];
  }
  cl = li/2;
  li = cl;
  
  
  for (int i=0; i<cl; i++)
   buff[i]=temp[i];
   
  for (int i=0; i<cl; i++)
   if(buff[i] == 0) buff[i] = 1000; 
  
  ToShow(buff, cl);
   
   }     
   
   cout<<endl;
    xe = temp[0];
   
    
    for (int i=0; i<size;i++) 
    if (a[i] == xe) 
    {
         a[i] = 1000;
         break;
    }
    
    ToShow(a,size);
    cout<<endl;
    
     }
     
int main()
{   
    srand(time(NULL));
    int ch,size,l, h, st, li;
    
    cout<<"Please, enter the down border!"<<endl;
    cin>>l;
    cout<<"Please, enter the up border!"<<endl;
    cin>>h;
     
     int sizes[5] = {10, 20, 30, 40, 80};
     long times[5] = {0};
     
      for(int sz = 0; sz < 1; sz++)
       {
        size = sizes[sz];
     
     st = stTwo(size);
     li = (int)pow(2,st);
     
     int a[li]; 
     int vec_sort[li];
     
     for(int i=0;i<size;i++)
     {
     a[i]=l+rand()%(h-l); 
     }  
     ToShow(a,size) ;
     cout<<endl;
  
     
     for (int i=size; i<li;i++)
     {
      a[i] = 1000;   
         }
   
      cout<<endl;   
    long time = GetTickCount();
     
     for(int i=0; i<size; i++)
     {
     TurnirSort(a,size,st,li);
     vec_sort[i] = xe;

     }
     time = GetTickCount()-time; 
     times[sz] = time;
     
     ToShow(vec_sort,size);
     
     cout<<endl;
    
     }
     cout<<endl;
     long max = times[0];
    for(int i = 0; i < 5; i++) {
        max = (times[i] > max) ? times[i] : max;
    }
    for(int i = 0; i < 5; i++) {
        cout << sizes[i] << "|";
        for(int j = 0; j < times[i] * 70. / max; j++) {
            cout << "*";
        }
        
        cout<<endl;
    }
    cout<<endl;
    cout<<" -------"<<"-"<<"-------"<<endl;
    cout<<" Sizes  "<<"|"<<"  Times"<<endl;
    cout<<" -------"<< "-"<<"-------"<<endl;
    for (int i=0; i<5; i++)
    {
        cout<<" "<<sizes[i]<<"   |  "<<times[i]<<endl;
        cout<<" -------"<< "-"<<"-------"<<endl; 
        }
    cout<<endl;
    
     getch();    
}


но проблема не ушла... Что-то с массивом buff[i] не так, возможно с размерностью напутал...


Эскизы прикрепленных изображений
Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 17.03.2009 23:45
Сообщение #13


Гость






Ты забыл инициализировать массив temp нулями, лучше всего прямо тут:
    for (int i=0; i<S; i++) {
        buff[i] = (i < size) ? a[i] : 0;
        temp[i] = 0; // <---
    }
Кстати, ты знаешь, что твоя программа стандарту не соответствует? Ты используешь GCC-шное дополнение, позволяющее передавать переменную в качестве размера массива, при попытке откомпилировать эту программу в Билдере получишь ошибки...
 К началу страницы 
+ Ответить 
Rocket
сообщение 23.03.2009 21:32
Сообщение #14


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


Вот реализация двух других известных методов сортировки, реализованных "под одной крышей" - сортировка Шелла и Быстрая сортировка:

#include<iostream>
#include<conio.h>
#include<windows.h>

using namespace std;

int increment(long inc[], long size) {
  int p1, p2, p3, s;

  p1 = p2 = p3 = 1;
  s = -1;
  do {
    if (++s % 2) {
      inc[s] = 8*p1 - 6*p2 + 1;
    } else {
      inc[s] = 9*p1 - 9*p3 + 1;
      p2 *= 2;
      p3 *= 2;
    }
	p1 *= 2;
  } while(3*inc[s] < size);  

  return s > 0 ? --s : 0;
}

void ShellSort(int *a, long size)
{

  long inc, i, j, k = 0, seq[40];
  int s;
  
s = increment(seq, size);

 while ( s >= 0)
 {
      
       inc = seq[s--];
       
    for (i = inc; i < size; i++)
     {
      int temp = a[i];

      for (j = i-inc; (j >= 0) && (a[j] > temp); j -= inc)
        a[j+inc] = a[j];
      a[j+inc] = temp;
    } 
    
      /* for(int i=0;i<size;i++)
                {
                  cout<<a[i]<<" ";
                }
     
         cout << endl << endl;*/                  
     
  }
}


void Q_Sort(int *a, long size)
{

  long i = 0, j = size; 		
  int temp, p;

  p = a[ size>>1 ];
  
    do
     {
    while ( a[i] < p ) i++;
    while ( a[j] > p ) j--;

    if (i <= j)
     {
      temp = a[i]; a[i] = a[j]; a[j] = temp;
      i++; j--;
    }
  } 
  while ( i<=j );


  if ( j > 0 ) Q_Sort(a, j);
  if ( size > i ) Q_Sort(a+i, size-i);
}
 

 
int main() {

while(true)
{
int ch,size,l, h;

cout<<"Please, enter the size of massive to sort!"<<endl;   
cin>>size;
cout<<"Please, enter the down border!"<<endl;
cin>>l;
cout<<"Please, enter the up border!"<<endl;
cin>>h;

int *a = new int[size]; 
int *b = new int[size]; 

float time, time_1 = 0, time_2 = 0;
     
        for (int j = 0; j < 100; j++)
        {
                
                     for(int i=0;i<size;i++)
                      {
                        a[i] = l+rand()%(h-l); 
                        b[i] = a[i];
                      }  
                      
                    time = GetTickCount();
                      
                   /*   for(int i=0;i<size;i++)
                {
                  cout<<a[i]<<" ";
                }
     
         cout << endl << endl;*/
                       
                  ShellSort(a, size); 
                  
        /*   for(int i=0;i<size;i++)
                {
                  cout<<a[i]<<" ";
                }
                
           cout << endl << endl;*/
                
                time_1 = time_1 + (GetTickCount()-time); 
                
          time = GetTickCount();
           Q_Sort(b, size);
           time_2 = time_2 + (GetTickCount()-time); 
               
                
                
       }
       
       
      cout<<"Shell's Sort Time:"<<time_1/100<<endl;
       
      cout<<"Quick's Sort Time:"<<time_2/100<<endl;
       
 
            delete a;
            delete b;
      
      ch = getch();
      if (ch==27) exit(1);
      else system("cls");
      
      
      }
      }


Проблема заключается в том, что при размере массива в диапазоне от 1000 и примерно до 10000, к примеру 3000, на этапе вывода среднего времени происходит вылет из программы, с размерность же меньше 1000 и на больших размерах, скажем 30000 и т.д. всё работает... С чем это связано?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 23.03.2009 21:39
Сообщение #15


Гость






Цитата
Please, enter the size of massive to sort!
3000
Please, enter the down border!
1
Please, enter the up border!
100
Shell's Sort Time:1.68
Quick's Sort Time:1.35

Process returned 1 (0x1) execution time : 46.890 s
Press any key to continue.
Размер = 3000, ничего не вылетело. Что я делаю не так?
 К началу страницы 
+ Ответить 
Rocket
сообщение 23.03.2009 21:55
Сообщение #16


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


Цитата(volvo @ 23.03.2009 21:39) *

Размер = 3000, ничего не вылетело. Что я делаю не так?

Тогда я вообще ничего не могу понять... у меня вылетает с ошибкой... хм... Ну а вообще по коду, по работе с массивами косяков не видно никаких? С чем такое может быть связано??
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 23.03.2009 22:42
Сообщение #17


Гость






CodeGuard нашел проблему:

void Q_Sort(int *a, long size)
{
  long i = 0, j = size;
  int temp, p;
  p = a[ size>>1 ];

  do
  {
    while ( a[i] < p ) i++;
    while ( a[j] > p ) j--; // <--- Здесь
// ...

, попытка обратиться к J-му элементу массива, в то время как доступны должны быть элементы от 0 до (j-1).
 К началу страницы 
+ Ответить 
Rocket
сообщение 23.03.2009 22:49
Сообщение #18


Знаток
****

Группа: Пользователи
Сообщений: 306
Пол: Мужской
Реальное имя: Евгений

Репутация: -  0  +


Цитата(volvo @ 23.03.2009 22:42) *
CodeGuard нашел проблему:
А как тогда это исправить?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 23.03.2009 23:09
Сообщение #19


Гость






Цитата
А как тогда это исправить?
А подумать?
void Q_Sort(int *a, long size)
{
	long i = 0, j = size - 1; // Здесь
	// ...

и

	delete [] a; // вместо delete a;
	delete [] b; // вместо delete b;
(если этого не сделать, программа под Билдером будет вылетать)
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 

- Текстовая версия 20.07.2025 9:22
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"