fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <assert.h>
  5.  
  6. struct TNode
  7. {
  8. int data;
  9. struct TNode *next;
  10. struct TNode *prev;
  11. };
  12.  
  13. struct TList
  14. {
  15. struct TNode *head;
  16. struct TNode *tail;
  17. };
  18.  
  19. void ListInit(struct TList *L)
  20. {
  21. assert(L);
  22. L->head = NULL;
  23. L->tail = NULL;
  24. }
  25.  
  26. int ListIsEmpty(struct TList *L)
  27. {
  28. assert(L);
  29. return L->head == NULL;
  30. }
  31.  
  32. void ListDisplayForward(struct TList* L)
  33. {
  34. assert(L);
  35. int counter = 0;
  36. struct TNode *curr = L->head;
  37. printf("List (head-->tail): ");
  38. while (curr != NULL)
  39. {
  40. printf("%d -> ", curr->data);
  41. curr = curr->next;
  42. counter++;
  43. }
  44. printf("NULL \n");
  45. printf("Liczba wezlow listy: %d \n", counter);
  46. }
  47.  
  48. void ListDisplayBackward(struct TList* L)
  49. {
  50. assert(L);
  51. int counter = 0;
  52. struct TNode *curr = L->tail;
  53. printf("List (tail-->head): ");
  54. while (curr != NULL)
  55. {
  56. printf("%d -> ", curr->data);
  57. curr = curr->prev;
  58. counter++;
  59. }
  60. printf("NULL \n");
  61. printf("Liczba wezlow listy: %d \n", counter);
  62. }
  63.  
  64. void ListInsertNodeTail(struct TList *L, struct TNode *p)
  65. {
  66. assert(L);
  67. assert(p);
  68. p->next = NULL;
  69. if (L->head == NULL)
  70. {
  71. p->prev = NULL;
  72. L->head = p;
  73. }
  74. else
  75. {
  76. L->tail->next = p;
  77. p->prev = L->tail;
  78. }
  79. L->tail = p;
  80. }
  81.  
  82. void ListInsertValueTail(struct TList *L, int k)
  83. {
  84. assert(L);
  85. struct TNode *node = (struct TNode *)malloc(sizeof(struct TNode));
  86. assert(node);
  87. node->data = k;
  88. ListInsertNodeTail(L, node);
  89. }
  90.  
  91. struct TNode *ListDetachHead(struct TList *L)
  92. {
  93. assert(L);
  94. struct TNode *temp = L->head;
  95. if (L->head)
  96. {
  97. if (L->head->next == NULL)
  98. L->tail = NULL;
  99. else
  100. L->head->next->prev = NULL;
  101. L->head = L->head->next;
  102. }
  103. return temp;
  104. }
  105.  
  106. void ListDeleteHead(struct TList *L)
  107. {
  108. assert(L);
  109. free(ListDetachHead(L));
  110. }
  111.  
  112. void ListDelete(struct TList *L)
  113. {
  114. assert(L);
  115. while (!ListIsEmpty(L))
  116. ListDeleteHead(L);
  117. }
  118.  
  119. void SwapNodePointers(struct TNode **A, struct TNode **B)
  120. {
  121. assert(A);
  122. assert(B);
  123. struct TNode *tmp = *A;
  124. *A = *B;
  125. *B = tmp;
  126. }
  127.  
  128. void SwapListPointers(struct TList **A, struct TList **B)
  129. {
  130. assert(A);
  131. assert(B);
  132. struct TList *tmp = *A;
  133. *A = *B;
  134. *B = tmp;
  135. }
  136.  
  137. int ListSplit(struct TList *L, struct TList *A, struct TList *B)
  138. {
  139. assert(L);
  140. assert(A);
  141. assert(B);
  142. // prevNode trzeba zainicjalizowac nullem, coby się nie wysypać na początku
  143. struct TNode *currNode, *prevNode = NULL;
  144. ListInit(A);
  145. ListInit(B);
  146. while (currNode = ListDetachHead(L)) // "odłączamy głowę", dopóki nie zwróci nulla
  147. {
  148. // jeśli mamy początek nowej serii, to zamieniamy ze sobą wskaźniki do list,
  149. // w ten sposób poniższy kod zapisujący do A będzie zapisywał naprzemiennie do list A, B
  150. // (coby kod niżej był prostszy - jeden przypadek zamiast dwóch)
  151. if (prevNode && prevNode->data > currNode->data)
  152. SwapListPointers(&A, &B);
  153.  
  154. // zawsze zapisujemy do A, ale A nie zawsze wskazuje tę samą listę
  155. ListInsertNodeTail(A, currNode);
  156. // pamiętamy poprzednią wartość (węzeł z wartością), coby wykryć koniec aktualnej serii
  157. prevNode = currNode;
  158. }
  159. return ListIsEmpty(B);
  160. }
  161.  
  162. void ListMerge(struct TList* A, struct TList* B, struct TList *L)
  163. {
  164. assert(L);
  165. assert(A);
  166. assert(B);
  167. struct TNode *tmpA, *tmpB, *prevA, *prevB;
  168. tmpA = ListDetachHead(A); // akutalna wartość z A
  169. tmpB = ListDetachHead(B); // akutalna wartość z B
  170. ListInit(L);
  171. while (tmpA && tmpB) // obie serie niepuste
  172. {
  173. // zapewnienie, że w A mamy serię z aktualnie niewiększą wartością,
  174. // w razie potrzeby zamieniamy odpowiednie wskaźniki
  175. // (coby kod niżej był prostszy - jeden przypadek zamiast dwóch)
  176. if (tmpA->data > tmpB->data)
  177. {
  178. SwapNodePointers(&tmpA, &tmpB);
  179. SwapNodePointers(&prevA, &prevB);
  180. SwapListPointers(&A, &B);
  181. }
  182.  
  183. // przepisanie aktualnej wartości z serii w A (czyli wartości niewiększej od tej z B)
  184. ListInsertNodeTail(L, tmpA);
  185. // i pobranie kolejnej
  186. prevA = tmpA;
  187. tmpA = ListDetachHead(A);
  188.  
  189. // sprawdzenie, czy była to ostatnia liczba z serii
  190. if (!tmpA || tmpA->data < prevA->data)
  191. {
  192. // jeśli tak, przenosimy do końca aktualną serię z B (na pewno jest niepusta)
  193. do
  194. {
  195. ListInsertNodeTail(L, tmpB);
  196. prevB = tmpB;
  197. tmpB = ListDetachHead(B);
  198. } while (tmpB && prevB->data <= tmpB->data);
  199. }
  200. }
  201. // w którejś z list (ale tylko jednej) mogły zostać jeszcze jakieś serie
  202. // upewniamy się, że ewentualne "resztki" są w A (tu żaden Swap nie jest potrzebny, można nadpisać)
  203. if (!tmpA)
  204. tmpA = tmpB;
  205. // przenosimy ewentualne "resztki"
  206. while (tmpA)
  207. {
  208. ListInsertNodeTail(L, tmpA);
  209. tmpA = ListDetachHead(A);
  210. }
  211. }
  212.  
  213. int main()
  214. {
  215. int k, n, m;
  216. struct TList L, L1, L2;
  217. ListInit(&L);
  218. srand(time(NULL));
  219. scanf("%d %d", &n, &m);
  220. for (k = 1; k <= n; k++)
  221. ListInsertValueTail(&L, rand() % m);
  222.  
  223. printf("List L \n");
  224. ListDisplayForward(&L);
  225. ListDisplayBackward(&L);
  226.  
  227. ListSplit(&L, &L1, &L2);
  228.  
  229. printf("\nList L1 \n");
  230. ListDisplayForward(&L1);
  231. ListDisplayBackward(&L1);
  232. printf("\nList L2 \n");
  233. ListDisplayForward(&L2);
  234. ListDisplayBackward(&L2);
  235.  
  236. ListMerge(&L1, &L2, &L);
  237.  
  238. printf("\nList L \n");
  239. ListDisplayForward(&L);
  240. ListDisplayBackward(&L);
  241.  
  242. ListDelete(&L);
  243.  
  244. system("PAUSE");
  245. return 0;
  246. }
Success #stdin #stdout #stderr 0s 9432KB
stdin
20 50
stdout
List L 
List (head-->tail): 6 -> 0 -> 15 -> 49 -> 16 -> 30 -> 40 -> 24 -> 49 -> 27 -> 12 -> 45 -> 1 -> 34 -> 42 -> 19 -> 26 -> 14 -> 2 -> 16 -> NULL 
Liczba wezlow listy: 20 
List (tail-->head): 16 -> 2 -> 14 -> 26 -> 19 -> 42 -> 34 -> 1 -> 45 -> 12 -> 27 -> 49 -> 24 -> 40 -> 30 -> 16 -> 49 -> 15 -> 0 -> 6 -> NULL 
Liczba wezlow listy: 20 

List L1 
List (head-->tail): 6 -> 16 -> 30 -> 40 -> 27 -> 1 -> 34 -> 42 -> 14 -> NULL 
Liczba wezlow listy: 9 
List (tail-->head): 14 -> 42 -> 34 -> 1 -> 27 -> 40 -> 30 -> 16 -> 6 -> NULL 
Liczba wezlow listy: 9 

List L2 
List (head-->tail): 0 -> 15 -> 49 -> 24 -> 49 -> 12 -> 45 -> 19 -> 26 -> 2 -> 16 -> NULL 
Liczba wezlow listy: 11 
List (tail-->head): 16 -> 2 -> 26 -> 19 -> 45 -> 12 -> 49 -> 24 -> 49 -> 15 -> 0 -> NULL 
Liczba wezlow listy: 11 

List L 
List (head-->tail): 0 -> 6 -> 15 -> 16 -> 30 -> 40 -> 49 -> 24 -> 27 -> 49 -> 1 -> 12 -> 34 -> 42 -> 45 -> 14 -> 19 -> 26 -> 2 -> NULL 
Liczba wezlow listy: 19 
List (tail-->head): 2 -> 26 -> 19 -> 14 -> 45 -> 42 -> 34 -> 12 -> 1 -> 49 -> 27 -> 24 -> 49 -> 40 -> 30 -> 16 -> 15 -> 6 -> 0 -> NULL 
Liczba wezlow listy: 19 
stderr
sh: 1: PAUSE: not found