Сортировка односвязного динамического списка - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Добрый вечер! Есть список и функции работы с ним(переходы к элементам, их удаление, поиск элементов по каким либо параметрам). Сама структура списка ->
Листинг программы
  1. struct list
  2. {
  3. int data;
  4. list *next;
  5. }; list *first=0, *nval=0;
Нужна помощь в написании функции сортировки : все нечетные элементы слева , четные справа (т.е - Дано: 27432195, после вызова должно получиться 13579224) В массивах знаю как это делать, а здесь блуждаю в указателях. Помогите разобраться.

Решение задачи: «Сортировка односвязного динамического списка»

textual
Листинг программы
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. typedef struct TList TList;
  5.  
  6. struct TList
  7. {
  8.     int Data;
  9.     TList *Next;
  10. };
  11.  
  12. /* функция добавления в список */
  13. void AddToList(TList **pBegin,const int a)
  14. {
  15.     TList* p=NULL;
  16.     if(*pBegin==NULL) /*новый список */
  17.     {
  18.         *pBegin=malloc(sizeof(**pBegin));
  19.         (*pBegin)->Data=a;
  20.         (*pBegin)->Next=NULL;
  21.     }
  22.     else
  23.     {
  24.         /* добавляем в конец */
  25.         p=*pBegin;
  26.         while(p->Next!=NULL) p=p->Next;
  27.         p->Next=malloc(sizeof(*p));
  28.         p->Next->Data=a;
  29.         p->Next->Next=NULL;
  30.     }  
  31. }
  32.  
  33. /* функция печати списка на экран */
  34. void PrintList(const TList* pBegin)
  35. {
  36.    
  37.     const TList *p=pBegin;
  38.     printf("%s\n","===== List values =====");
  39.     while(p!=NULL)
  40.     {
  41.         printf("%p%s%i\n",p,": ",p->Data);
  42.         p=p->Next;
  43.     }
  44.     if(pBegin==NULL) printf("%s\n","List is empty");
  45. }
  46.  
  47. /* функция очистки списка */
  48. void ClearList(TList** pBegin)
  49. {
  50.     TList *p=NULL;
  51.     while(*pBegin!=NULL)
  52.     {
  53.         p=(*pBegin)->Next;
  54.         free(*pBegin);
  55.         *pBegin=p;
  56.     }
  57. }
  58.  
  59. /* функция сортировки списка по возрастанию */
  60. void SortList(TList** pBegin)
  61. {
  62.     int NodesCount=0;   /* количество узлов в списке */
  63.     TList** Nodes=NULL; /* массив указателей на узлы списка */
  64.     int i,j;            /* переменные циклов */
  65.     TList* temp;        /* параметр */
  66.     /* считаем число узлов в списке */
  67.     temp=*pBegin;
  68.     while(temp!=NULL)
  69.     {
  70.         NodesCount=NodesCount+1;
  71.         temp=temp->Next;
  72.     }
  73.     if(NodesCount!=0)
  74.     {
  75.         Nodes=malloc(NodesCount*sizeof(*Nodes));
  76.         i=0;
  77.         /* копируем адреса узлов в массив */
  78.         temp=*pBegin;
  79.         while(temp!=NULL)
  80.         {
  81.             Nodes[i]=temp;
  82.             i=i+1;
  83.             temp=temp->Next;
  84.         }
  85.         /* сортировка массива пузырьком */
  86.         for(j=0;j<NodesCount;j++)
  87.         {
  88.             for(i=0;i<NodesCount-1;i++)
  89.             {
  90.                 if((Nodes[i]->Data)>(Nodes[i+1]->Data))
  91.                 {
  92.                     temp=Nodes[i];
  93.                     Nodes[i]=Nodes[i+1];
  94.                     Nodes[i+1]=temp;
  95.                 }
  96.             }
  97.         }
  98.         /* восстанавливаем векторность списка */
  99.         for(i=0;i<NodesCount-1;i++) Nodes[i]->Next=Nodes[i+1];
  100.         Nodes[NodesCount-1]->Next=NULL;
  101.         /* возвращаем модифицированный список */
  102.         *pBegin=Nodes[0];
  103.         free(Nodes);
  104.     }
  105. }
  106.  
  107. /* функция обработки списка */
  108. void ProcessList(TList** pBegin)
  109. {  
  110.     TList* EvenStart=NULL;  /* указатель на начало списка, содержащего четные данные */
  111.     TList* EvenEnd=NULL;    /* указатель на последний элемент списка с четными данными */
  112.     TList* OddStart=NULL;   /* --//-- нечетные */
  113.     TList* OddEnd=NULL;     /* --//-- последний + нечетные */
  114.     TList* p=NULL;          /* итератор списка */
  115.     TList* next=NULL;       /* указатель на последующий элемент в списке */
  116.     p=*pBegin;
  117.     while(p!=NULL)
  118.     {
  119.         next=p->Next;   /* запоминаем адрес следующего элемента в списке */
  120.         if(p->Data%2==0)
  121.         {
  122.             if(EvenStart==NULL) /* начинаем список с четными данными */
  123.             {
  124.                 EvenStart=p;
  125.                 EvenStart->Next=NULL;              
  126.                 EvenEnd=EvenStart;
  127.             }
  128.             else
  129.             {
  130.                 /* перебрасываем адреса */
  131.                 EvenEnd->Next=p;
  132.                 EvenEnd=EvenEnd->Next;
  133.                 EvenEnd->Next=NULL;
  134.             }
  135.         }
  136.         else
  137.         {
  138.             if(OddStart==NULL)  /* начинаем список с нечетными данными */
  139.             {
  140.                 OddStart=p;
  141.                 OddStart->Next=NULL;
  142.                 OddEnd=OddStart;
  143.             }
  144.             else
  145.             {
  146.                 OddEnd->Next=p;
  147.                 OddEnd=OddEnd->Next;
  148.                 OddEnd->Next=NULL;
  149.             }
  150.         }
  151.         p=next; /* идем к следующему элементу */
  152.     }
  153.     SortList(&EvenStart);   /* сортируем список с четными данными */
  154.     SortList(&OddStart);    /* сортируем список с нечетными данными */
  155.    
  156.     if(OddStart!=NULL)  /* если есть вообще нечетные данные */
  157.     {
  158.         /* сшиваем конец списка с нечетными данными со списком с четными и возвращаем */
  159.         p=OddStart;
  160.         while(p->Next!=NULL) p=p->Next;
  161.         p->Next=EvenStart;
  162.         *pBegin=OddStart;
  163.     }
  164.     else *pBegin=EvenStart;
  165. }
  166.  
  167.  
  168. int main(void)
  169. {
  170.     TList* a=NULL;  /* указатель на начало списка */
  171.     int k=0;
  172.     int i=0;
  173.     for(i=0;i<10;i++)
  174.     {
  175.         scanf("%d",&k);
  176.         AddToList(&a,k);
  177.     }
  178.     PrintList(a);
  179.     ProcessList(&a);
  180.     PrintList(a);
  181.     ClearList(&a);
  182.     getchar();
  183.     return 0;
  184. }

Объяснение кода листинга программы

  1. В функции AddToList новый узел списка добавляется в конец списка. Если список пуст, то новый узел становится началом списка.
  2. Функция PrintList печатает значения узлов списка в формате Значение: адрес. Если список пуст, то выводится сообщение List is empty.
  3. Функция ClearList проходит по списку и освобождает память, занимаемую каждым узлом, перед чем сохраняя адрес следующего узла.
  4. Функция SortList сортирует список по возрастанию. Для этого список копируется в массив указателей на узлы, затем проводится сортировка массива пузырьком. После сортировки массива восстанавливается векторность списка и обновленный список возвращается.
  5. В функции ProcessList списки с четными и нечетными данными разделяются. Затем каждый из этих списков сортируется с помощью функции SortList. После сортировки списки с четными и нечетными данными объединяются в один список.
  6. В функции main создается пустой список a. Затем в цикле с помощью функции AddToList в список добавляются 10 узлов с различными значениями. После этого список печатается с помощью функции PrintList. Затем список обрабатывается с помощью функции ProcessList, сортируется и снова печатается с помощью функции PrintList. После этого список очищается с помощью функции ClearList.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 4.267 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы