N4.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. #include <stdio.h>
  2. #include <malloc.h>
  3. struct ListElement
  4. {
  5. int elem;
  6. struct ListElement* next;
  7. };
  8. typedef struct ListElement Element;
  9. typedef Element* List;
  10. List createList(int n)
  11. {
  12. //проверка на плешивость
  13. if (n < 1) return NULL;
  14. List head = calloc(1, sizeof(Element));//создаем голову, от которой будем шагать
  15. head->elem = 1;//присваиваем значение гоовы
  16. head->next = NULL;//следующего элемента массива пока нет, поэтому никуда не ведет
  17. List current = head, next;//создаем экземпляры для текущего и сдедующего элементов
  18. //расширяем лист до момента, пока не закончатся элементы
  19. for (size_t i = 1; i < n; i++)
  20. {
  21. next = calloc(1, sizeof(Element));//выделяем память для следующего элемента
  22. current->next = next;//адресс следующего элемента записываем соответствующую ячейку текущего
  23. next->elem = i + 1; //присваиваем значение следующей ячейки
  24. current = next;//текущая ячеука становится следующей
  25. }
  26. current->next = NULL;//поскольку это последний элемент, то ссылки на след быть не может
  27. return head;
  28. }
  29. void showList(List list)
  30. {
  31. if (!list) return NULL;
  32. while (list)
  33. {
  34. printf("%d ", list->elem);
  35. list = list->next;
  36. }
  37. printf("\n");
  38. }
  39. void deleteList(List list)
  40. {
  41. if (list->next == NULL) return NULL; //если лист пустой возвращаем NULL
  42. while (list->next)//идем в цикле пока у элемента есть ссылка на следующий элемент
  43. {
  44. List previous = list;//создаем ссылку на текущий элемент
  45. list = list->next;//переходим на следующий элемент
  46. //free(previous);//текущий элемент
  47. }
  48. free(list);//освобождем последний элемент
  49. }
  50. List insertIn(List list, int place, Element value)
  51. {
  52. List head = calloc(1, sizeof(Element));
  53. if (place <= 0)
  54. {
  55. head->elem = value.elem;
  56. head->next = list;
  57. }
  58. else
  59. {
  60. head = list;
  61. for (size_t i = 0; i < place - 1; i++)
  62. {
  63. if (list->next)list = list->next;
  64. }
  65. value.next = list->next;
  66. list->next = &value;
  67. }
  68. return head;
  69. }
  70. List deleteElement(List list, int place)
  71. {
  72. place -= 1;//приводим к индексам
  73. if (place <= 0)//если 1 позиция или номер позиции меньше 0
  74. {
  75. List head = list->next; //новое начало коллекции
  76. free(list);//освобождение памяти
  77. return(head);//ссылка на новое начало
  78. }
  79. else
  80. {
  81. List head = list;//ссылка на начало
  82. for (size_t i = 0; i < place - 1; i++)//идем пока не дойдем до нужного элемента
  83. {
  84. if (list->next->next)//проверка на наличие продолжение у последующего элемента есть
  85. {
  86. if (list->next)list = list->next; //проверяем есть ли ссылка
  87. else break;//если ссылки нет, значит место больше количества листа и удаляем последний элемент
  88. }
  89. else break;
  90. }
  91. if (list->next->next)//проверяем есть ли какой-то элемент дальше, после удаляемого
  92. {
  93. List elem = list->next->next;//создаем ссылку на следующий после удаляемого элемент
  94. free(list->next);//освобождаем память
  95. list->next = elem;//меняем ссылку на следующий элемент
  96. }
  97. else //позиция больше нужной освобождаем последний элемент
  98. {
  99. List elem = list->next;
  100. list->next = NULL;
  101. free(elem);//освобождаем память
  102. }
  103. return(head);//возвращаем начало
  104. }
  105. }
  106. List replaceElement(List list, int place1, int place2)
  107. {
  108. if (place1 > 0 && place1 < place2)
  109. {
  110. List head = list;//ссылка на начало
  111. int num = 0;//счетчик
  112. place1 -= 1;//приводим к индексам
  113. place2 -= 1;//приводим к индексам
  114. List lastElem1 = calloc(1, sizeof(Element));
  115. if (place1 != 0)
  116. {
  117. for (size_t i = 0; i < place1 - 1; i++)//идем до первого элемента
  118. {
  119. if (list->next)
  120. {
  121. list = list->next;
  122. num++;
  123. }
  124. else break;
  125. }
  126. lastElem1 = list;//запоминаем 1 предыдущий элемент
  127. }
  128. else
  129. {
  130. lastElem1 = head;
  131. }
  132. for (size_t i = num; i < place2 - 1; i++)//идем до второго элемента
  133. {
  134. if (list->next)list = list->next;
  135. else break;
  136. }
  137. List lastElem2 = list;//запоминаем 2 предыдущий элемент
  138. if (lastElem2 == lastElem1)
  139. {
  140. lastElem2 = lastElem2->next;
  141. }
  142. if (lastElem2->next && lastElem1->next)
  143. {
  144. if (place1 != 0 && lastElem1->next != lastElem2)//любой не соседний и не 1 элемент
  145. {
  146. //запоминаем элементы которыми меняемся
  147. List elem1 = lastElem1->next;
  148. List elem2 = lastElem2->next;
  149. //меняем ссылки на следующий элемент
  150. List freeEl = calloc(1, sizeof(Element));
  151. freeEl->next = list->next->next;
  152. elem2->next = elem1->next;
  153. elem1->next = freeEl->next;
  154. free(freeEl);
  155. //меняем ссылки предыдущих элементов на новые
  156. lastElem1->next = elem2;
  157. lastElem2->next = elem1;
  158. return head;//возвращаем начало
  159. }
  160. else if (lastElem1->next != lastElem2)//1 элемент с каким нибудь другим
  161. {
  162. //запоминаем элементы которыми меняемся
  163. List elem1 = head;
  164. List elem2 = lastElem2->next;
  165. //меняем ссылки на следующий элемент
  166. List freeEl = calloc(1, sizeof(Element));
  167. freeEl->next = list->next->next;
  168. elem2->next = elem1->next;
  169. elem1->next = freeEl->next;
  170. free(freeEl);
  171. //меняем ссылки предыдущих элементов на новые
  172. lastElem2->next = elem1;
  173. return elem2;//возвращаем новое начало
  174. }
  175. else if (place1 != 0)//соседние элементы
  176. {
  177. //запоминаем элементы которыми меняемся
  178. List elem1 = lastElem1->next;
  179. List elem2 = lastElem2->next;
  180. //меняем ссылки на следующий элемент
  181. List freeEl = calloc(1, sizeof(Element));
  182. freeEl->next = elem2->next;
  183. if (freeEl->next)elem1->next = freeEl->next;
  184. else return list;
  185. free(freeEl);
  186. elem2->next = elem1;
  187. //меняем ссылки предыдущих элементов на новые
  188. lastElem1->next = elem2;
  189. return head;//возвращаем начало
  190. }
  191. else if (place1 == 0 && place2 == 1)
  192. {
  193. List elem1 = lastElem1;
  194. List elem2 = lastElem2;
  195. head = elem2;
  196. elem1->next = elem2->next;
  197. head->next = elem1;
  198. }
  199. else//соседние элементы 1 из которых голова
  200. {
  201. //запоминаем элементы которыми меняемся
  202. List elem1 = head;
  203. List elem2 = lastElem2->next;
  204. //меняем ссылки на следующий элемент
  205. List freeEl = calloc(1, sizeof(Element));
  206. freeEl->next = elem2->next;
  207. if (freeEl->next)elem1->next = freeEl->next;
  208. else return list;
  209. elem2->next = head;
  210. free(freeEl);
  211. return elem2;//возвращаем новое начало
  212. }
  213. }
  214. else
  215. {
  216. return head;
  217. }
  218. }
  219. else return list;
  220. }
  221. int main()
  222. {
  223. int n = 10;
  224. //printf("%d %d", sizeof(List), sizeof(Element));
  225. List newList = createList(n);//создание
  226. showList(newList);//вывод на экран
  227. Element elem = { 45, NULL };//создаем новый элемент
  228. newList = insertIn(newList, 2, elem);//добавление элемента в лист
  229. showList(newList);
  230. newList = deleteElement(newList, 1);//удаление элемента
  231. showList(newList);
  232. newList = replaceElement(newList, 1, 5);//замена элементов местами
  233. showList(newList);
  234. //1 и 2 элемент обмен
  235. deleteList(newList);//удаление
  236. }