LINUX.ORG.RU

Сортировка структуры

 , ,


2

2

Доброе время суток.
Задался целью отсортировать структуру двумя методами.
Пузырьком и быстрой сортировкой. Сортировка qsort работает как нужно - поля меняются местами, а вот в пузырьке меняются местами только цифры, по которым происходит сортировка.
Оно и понятно, ведь со структурой мы ничего, кроме перестановки цифр не делаем.

Вопрос
Как правильно сортировать структуру пузырьком ?

typedef struct  STR{
    char fio[N];
    char dolzn[N];
    int stage;
    int oklad;
    char fack[N];
    char date_create[N];
    }
    st;

    int n=0;
    st sts[N];

int zarp(const void* a, const void* b)
{
    const st* k = (const st*)a;
    const st* m = (const st*)b;
    int s = ((k -> oklad) - (m -> oklad));    
    return s;
}

void bubble_sort() 
 {
 for (int i = 0 ; i < n ; i++)
       {
         for (int j = 0 ; j < n - 1 - i  ; j++)
          {
               if (sts[j].oklad > sts[j+1].oklad )
              {
               int tmp= sts[j].oklad;
               sts[j].oklad = sts[j+1].oklad;
               sts[j+1].oklad = tmp;  
               }
           }
        }

  print2();
  }



int main()
{
    ifstream ar("in.cpp");
    n=count(istreambuf_iterator<char>(ar),
    istreambuf_iterator<char>(), '\n');


    ifstream in;
    in.open("in.cpp");
   
   for (int i = 0; i < n; ++i)
      {
        in>>sts[i].fio;
        in>>sts[i].dolzn;
        in>>sts[i].stage;
        in>>sts[i].oklad;
        in>>sts[i].fack;
        in>>sts[i].date_create;
          }

        print();
	bubble_sort();
        
        qsort(sts, n , sizeof(st), zarp);
        print2();
	

in.close();
return 0;
}

Полный код http://pastebin.com/qLe5Juwi



Последнее исправление: cetjs2 (всего исправлений: 2)

Чувствуется - учёба началась.

Для начала сделай массив указателей на структуры и меняй местами указатели, а не поля.

Ну и по-мелочи: ввод/вывод и сравнение лучше сделать отдельными подпрограммами.

В алгоритм не вникал.

ziemin ★★
()
Ответ на: комментарий от ziemin

сделай массив указателей

а если просто N записей вида st sts[N] ?

и меняй местами указатели, а не поля.

чем это будет отличаться от обращения вида sts[i].oklad ?
всё равно будут меняться только цифры.

C_student
() автор топика
Ответ на: комментарий от ziemin

а так оно сразу будет переставляться ?

значит вместр st sts[N] нужно создавать массив указателей на структуры ?
можно пример ?
и как потом обращаться к элементам структуры ?

C_student
() автор топика
Ответ на: комментарий от C_student

Что бы не возится с malloc можно сделать так:

// Массив указателей.
struct STR * ptrs[];

// где-то в main, после ввода всех структур:
for (int i = 0; i < N; i++) {
  ptrs[i] = &sts[i];
}

Дальше в твоём пузырьке (кстати замени n на N везде):

// допустим подпрограмма сравнения есть. 0: равны, 1: A > B, -1: B > A
int cmpSTR(struct STR * A, struct STR * B);

// времянка для обмена
struct STR *tmp = NULL;
if (cmpSTR(ptrs[i],ptrs[i+1]) > 0) {
  tmp = ptrs[i];
  ptrs[i] = ptrs[i+1];
  ptrs[i+1] = tmp;
}

В общем как-то так. Обращаться к структуре через ->. Например ptrs[0]->oklad это как sts[12].oklad.

ziemin ★★
()
Ответ на: комментарий от ziemin

Кстати, в принципе, можно структуры сразу присваивать (типа sts[0] = sts[1], без указания полей). Это если с указателями возиться не хочешь.

ziemin ★★
()
Ответ на: комментарий от C_student

Hint: тебе нужен масив указателей на элементы структуры, который собственно и сортируется.

UPD: и да, ты уж определись C или C++ — читать твой код глаза вытекают.

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от ziemin

Не. Я тоже попался. Он перед чтением считает новые строки.

Точно, есть такое дело. Из-за форматирования не заметил. Впрочем, чему равно N, и почему не проверяется выход за границы я так и не понял.

andreyu ★★★★★
()
Ответ на: комментарий от ziemin

В полной версии N 100, но проверок нет :) С другой стороны кто будет вводить на лабах 100+ записей?

«Да кто станет подавать на вход непечатаемые символы» (с) народное.

andreyu ★★★★★
()
Ответ на: комментарий от ziemin

там простое считывание из файла ну а на ввод из грида проверок делать не нужно ибо проверяющий человек будет тестировать совсем другой функционал.

C_student
() автор топика
Ответ на: комментарий от ziemin

сделал через массив указателей, так ещё сложнее (

думаю сейчас сделать что-то вроде

st sts[N];
st buf[N];

и в buf засовывать значения, чтобы потом переставлять но вот деталей реализации пока нет, сейчас буду что-то пробовать сделать )

C_student
() автор топика
Ответ на: комментарий от C_student

вроде сделал нужно было ещё в пузырёк добавить перестановку остальных полей, вроде очевидно, но я не уверен правильно ли это

              char buf[N];
               strcpy(buf, sts[j].fio);
               strcpy(sts[j].fio, sts[j+1].fio);
               strcpy(sts[j+1].fio, buf);

C_student
() автор топика
Ответ на: комментарий от C_student

Надеюсь, ты понимаешь, что это плохое решение и так делать никогда не надо? Теперь при сортировке у тебя будут бессмысленно гоняться байты туда-сюда.

ziemin ★★
()
Ответ на: комментарий от beastie

У пузырька, как и любого другого алгоритма, есть диапазоны, при котором он эффективнее любого другого алгоритма (где-то когда-то читал). Как частный случай можно рассмотреть массив с единственным непорядочным элементом.

arturpub ★★
()
Ответ на: комментарий от ziemin

до этого было

               int tmp= sts[j].oklad;
               sts[j].oklad = sts[j+1].oklad;
               sts[j+1].oklad = tmp;

               strcpy(buf, sts[j].fio);
               strcpy(sts[j].fio, sts[j+1].fio);
               strcpy(sts[j+1].fio, buf);

               strcpy(buf, sts[j].dolzn);
               strcpy(sts[j].dolzn, sts[j+1].dolzn);
               strcpy(sts[j+1].dolzn, buf);

               strcpy(buf, sts[j].fack);
               strcpy(sts[j].fack, sts[j+1].fack);
               strcpy(sts[j+1].fack, buf);

               strcpy(buf, sts[j].date_create);
               strcpy(sts[j].date_create, sts[j+1].date_create);
               strcpy(sts[j+1].date_create, buf);

               tmp= sts[j].stage;
               sts[j].stage = sts[j+1].stage;
               sts[j+1].stage = tmp;
Не думаю, что оно лучше.
Использование пузырька - это уже плохое решение, так что я не знаю, как сделать лучше и нужно ли.
сейчас там немного улученный вариант обычного пузырька
bool fl=1;
  while (fl)
       {
       fl=0;
       for (int j = 0 ; j < n -1 ; j++)
          {
           if (sts[j].oklad > sts[j+1].oklad )

             {
               fl=1;
               st tmp= sts[j];
               sts[j] = sts[j+1];
               sts[j+1] = tmp;
              }
           }
        }

C_student
() автор топика
Ответ на: комментарий от C_student

до этого было

При этом тоже бессмысленно гонялись байты, так что один фиг. Зря ты указатели не сортируешь.

Кстати есть нехилая вероятность, что твой препод не в курсе такой возможности :). Используется редко из-за побочных эффектов.

ziemin ★★
()
Ответ на: комментарий от ziemin

был бы это реальный проект - сортировал бы указатели а для лабы нет смысла усложнять разве что закрепить навыки владения

C_student
() автор топика
Ответ на: комментарий от C_student

Кстати, помпю у меня подобное задание было. Типа визулизировать сортировку.

Все налепили списков и сделали свой вариант.

А я полез в вики, подсмотрел, как в разных реализациях переменные называются и замутил такие свойства у формы :). После этого всё, что мне оставалось - тупо копировать код из вики и цеплять к кнопкам. За часок я «реализовал» все, какие нашел :)

ziemin ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.