Advertisement
globalbus

Untitled

May 17th, 2011
354
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.14 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "list.h"
  4.  
  5. int List_Push(List** p_list, int value)
  6. /*
  7. Co robi: Dodaje element na początek listy
  8. Pobiera: wskaźnik do wskaźnika początku listy, wartość do wstawienia.
  9. */
  10. {
  11. List *new_element = malloc(sizeof(List));//rezerwuj pamięć
  12. if(!new_element)
  13. return 1;//malloc fail
  14. new_element-> data = value;//dodaj wartość
  15. new_element->next = *p_list;//ustaw wskaźnik next na początek starej listy
  16. *p_list=new_element;//ustaw adres przekazanej listy na nowy element
  17. return 0;
  18. }
  19.  
  20. int List_Add(List** p_list, int value)
  21. /*
  22. Co robi: Dodaje element na koniec listy
  23. Pobiera: wskaźnik do wskaźnika początku listy, wartość do wstawienia.
  24. */
  25. {
  26. List *element =*p_list; //pobierz adres
  27. if(element==NULL) //jeśli pusta lista
  28. {
  29. List_Push(p_list, value);//wywołaj dodawanie na początek
  30. return 0;
  31. }
  32. while(element->next!=NULL) //szukaj wskazania na koniec (NULL terminator)
  33. {
  34. element=element->next;//przeskakuj po liście
  35. }
  36. element->next = malloc(sizeof(List));//rezerwuj pamięć i zapisz ten adres zamiast NULL
  37. if(element->next==NULL)//malloc fail
  38. return 1;
  39. element=element->next;//przesuwamy się na nowy, ostatni element
  40. element->next=NULL;//dodajemy terminator
  41. element->data=value;//wpisujemy wartość
  42. return 0;
  43. }
  44. int List_Add_List(List** p_list_p, List** p_list_s, int index)
  45. /*
  46. Co robi: Dodaje listę (p_list_s) pod index innej listy (p_list_p)
  47. Pobiera: wskaźnik do wskaźnika początku listy bazowej, wskaźnik do wskaźnika początku listy wstawianej, index pod który wstawiamy
  48. */
  49. {
  50. int i=0;
  51. List *base =*p_list_p; //początek bazowej
  52. List *put =*p_list_s; //początek wstawianej
  53. while(put->next!=NULL) //poruszamy się na koniec listy wstawianej
  54. {
  55. put =put->next;
  56. }
  57. if(index==0) //jeśli wstawiamy na początek
  58. {
  59.  
  60. put->next=*p_list_p;//początek listy bazowej staje się ostatnim elementem wstawianej
  61. *p_list_p=*p_list_s;//nowy początek listy staje się początkiem listy wstawianej
  62. return 0;
  63. }
  64. for(i=0; i<index-1; ++i) //przesuwamy się pod index na liście bazowej
  65. {
  66. base=base->next;
  67. }
  68. put->next=base->next;//pod końcem listy wstawianej wstawiamy adres elementu zapisanego jako "następny"
  69. base->next=*p_list_s;//pod "następnym" w liście bazowej o zadanym indeksie wstawiamy adres początku listy wstawianej
  70. return 0;
  71. }
  72.  
  73. int List_Add_At(List** p_list, int value, int index)
  74. /*
  75. Co robi: Dodaje element w wyznaczonym indeksie
  76. Pobiera: wskaźnik do wskaźnika początku listy, wartość do wstawienia, index
  77. */
  78. {
  79. int i=0;
  80. List *element =*p_list;//pobierz adres
  81. List *next_element;
  82. if(index==0)//jeśli wstaw na początek
  83. {
  84. List_Push(p_list, value);
  85. return 0;
  86. }
  87.  
  88. for(i=0; i<index-1; ++i) //przesuń się pod wskazany index
  89. {
  90. element=element->next;
  91. }
  92. next_element=element->next;//zapamiętaj element następujący
  93. element->next= malloc(sizeof(List));//rezerwuj pamięć i przypisz do wskaźnika poprzedzającego
  94. if(element==NULL)//malloc fail
  95. return 1;
  96. element=element->next;//przesuń się na element wstawiany
  97. element->next=next_element;//wstaw adres następującego
  98. element->data=value;//wstaw wartość
  99. return 0;
  100. }
  101.  
  102. int List_Count(List* p_list)
  103. /*
  104. Co robi: Liczy ilość elementów listy
  105. Pobiera: wskaźnik początku listy
  106. */
  107. {
  108. int count=0;
  109. List *element =p_list->next;
  110. if(p_list==NULL)//jeśli pusta
  111. return 0;
  112. while(element!=NULL)//szukaj końca i zliczaj elementy
  113. {
  114. element =element->next;
  115. count++;
  116. }
  117. count++;
  118. return count; //zwróć licznik
  119. }
  120.  
  121. int List_Get(List* p_list, int index)
  122. /*
  123. Co robi: zwraca dane z wyznaczonego indeksu listy
  124. Pobiera: wskaźnik początku listy, index
  125. */
  126. {
  127. int i=0;
  128. for(i=0; i<index; ++i) //szukaj indeksu
  129. {
  130. p_list=p_list->next;
  131. }
  132. return p_list->data;//zwróć wartość
  133. }
  134.  
  135. void List_Print_All(List* p_list)
  136. /*
  137. Co robi: drukuje wszystkie elementy listy
  138. Pobiera: wskaźnik początku listy
  139. */
  140. {
  141. while(p_list!=NULL)//przesuwaj się do końca
  142. {
  143. printf("%d\t",p_list->data);//drukuje dane
  144. p_list=p_list->next;
  145. }
  146. printf("\n");
  147. }
  148.  
  149. int List_Del(List** p_list, int index)
  150. {
  151. /*
  152. Co robi: usuwa element spod wybranego indeksu
  153. Pobiera: wskaźnik do wskaźnika początku listy, index
  154. */
  155. int i;
  156. List *element =*p_list;
  157. List *previous_element;
  158. List *next_element;
  159. if(index==0)//jeśli kasujemy pierwszy
  160. {
  161. *p_list=element->next;//nowy początek listy to teraz element o indeksie 1
  162. free(element);//uwolnij pamięć spod elementu o indeksie 0
  163. return 0;
  164. }
  165. for(i=0; i<index-1; ++i) //szukaj indeksu
  166. {
  167. element=element->next;
  168. }
  169. previous_element=element;//zapamiętaj poprzedzający element
  170. element=element->next;//przesuń się o jeden
  171. next_element=element->next;//zapamiętaj następny element
  172. previous_element->next=next_element;//połącz poprzedzający i następny
  173. free(element);//uwolnij pamięć spod elementu o zadanym indeksie
  174. return 0;
  175. }
  176.  
  177. int List_Del_All(List** p_list)
  178. /*
  179. Co robi: usuwa całą listę i ustawia wskaźnik do niej na terminator NULL
  180. Pobiera: wskaźnik do wskaźnika początku listy
  181. */
  182. {
  183. List *element =*p_list;//bieżący element
  184. List *temp;
  185. while(element!=NULL)//przesuwaj się do końca
  186. {
  187. temp=element;//zapamiętaj adres
  188. element=element->next;//przesuń się na następny
  189. free(temp);//skasuj spod zapisanego adresu
  190. }
  191. *p_list=NULL; //pod listę wpisz NULL
  192. return 0;
  193. }
  194. int List_Add_ToSorted(List** p_list, int value, int sort_direction)
  195. /*
  196. Co robi: wstawia wartość w odpowiednie miejsce na posortowanej liście
  197. Pobiera: wskaźnik do wskaźnika początku listy, wartość, kierunek sortowania (1 dla malejącego, 0 dla rosnącego)
  198. */
  199. {
  200. List *element =*p_list;
  201. List *next_element;
  202. if(element==NULL || (element->data>=value)^sort_direction) //jeśli pusta lub wstawianie przed pierwszy element
  203. {
  204. List_Push(p_list, value);
  205. return 0;
  206. }
  207. while((element->next) && (element->next->data<value)^sort_direction) //jeśli nie osiągnie końca lub wartość z indeksem jeden do przodu nie będzie spełniała nierówności
  208. element=element->next;//przesuwanie
  209. next_element=element->next;//zapamiętaj element następujący
  210. element->next= malloc(sizeof(List));//rezerwuj pamięć i przypisz do wskaźnika poprzedzającego
  211. if(element==NULL)//malloc fail
  212. return 1;
  213. element=element->next;//przesuń się na element wstawiany
  214. element->next=next_element;//wstaw adres następującego
  215. element->data=value;//wstaw wartość
  216. return 0;
  217. }
  218.  
  219. int List_Sort_Selection_Sort(List** p_list, int sort_direction)
  220. /*
  221. Co robi: sortuje listę poprzez proste wybieranie, mało wydajne.
  222. Pobiera: wskaźnik do wskaźnika początku listy, kierunek sortowania (1 dla malejącego, 0 dla rosnącego)
  223. */
  224. {
  225. List *element =*p_list;//pobierz początek starej listy
  226. List *new_list=NULL;//nowa lista
  227. List *temp=NULL;//temp
  228. while(element->next)//przesuwanie się po liście
  229. {
  230. List_Add_ToSorted(&new_list,element->data,sort_direction);//dodaj element ze starej do nowej
  231. temp=element; //zapamiętaj adres bieżącego elementu
  232. element=element->next;//przesuń się o jeden do przodu
  233. free(temp);//uwolnij pamięć z wykorzystanego elementu
  234. }
  235. List_Add_ToSorted(&new_list,element->data,sort_direction);//dodaj ostatni element
  236. free(element);//zwolnij ten element
  237. *p_list=new_list;//podstaw nową listę w miejsce starej
  238. return 0;
  239. }
  240. List* List_GetRange(List* p_list, int start, int count)
  241. /*
  242. Co robi: zwraca wybrany zakres jako nową tablicę
  243. Pobiera: wskaźnik do początku listy, indeks startowy i długość kopiowanego fragmentu
  244. */
  245. {
  246. int i;
  247. List *new_list=NULL;
  248. for(i=0; i<start; ++i)
  249. p_list=p_list->next; //przesuń się pod adres startu
  250. for(i=0; i<count; ++i)
  251. {
  252. List_Add(&new_list,p_list->data);//kopiuj dane
  253. p_list=p_list->next;
  254. }
  255. return new_list;//zwróc skopiowany fragment
  256. }
  257. int List_Merge(List** p_list_a,List** p_list_b, int sort_direction)
  258. /*
  259. Co robi: łączy dwie listy posortowane w tym samym kierunku i zwraca adres we wskaźniku pierwszej listy
  260. Pobiera: wskaźnik do wskaźnika początku listy 1, wskaźnik do wskaźnika początku listy 2, kierunek sortowania (1 dla malejącego, 0 dla rosnącego)
  261. */
  262. {
  263. List *new_list=NULL;
  264. List *a=*p_list_a;
  265. List *b=*p_list_b;
  266. while (a&&b)
  267. {
  268. if ((a->data < b->data)^sort_direction)
  269. {
  270. List_Add(&new_list,a->data);
  271. a=a->next;
  272. }
  273. else
  274. {
  275. List_Add(&new_list,b->data);
  276. b=b->next;
  277. }
  278. }
  279. if(a)
  280. while(a)
  281. {
  282. List_Add(&new_list,a->data);
  283. a=a->next;
  284. }
  285. else
  286. while(b)
  287. {
  288. List_Add(&new_list,b->data);
  289. b=b->next;
  290. }
  291. List_Del_All(p_list_a);
  292. List_Del_All(p_list_b);
  293. *p_list_a=new_list;
  294. return 0;
  295. }
  296. List* List_MergeSort(List** p_list, int sort_direction)
  297. /*
  298. Co robi: Sortuje listy rekurencyjną metodą mergesort
  299. Pobiera: wskaźnik do wskaźnika początku listy, kierunek sortowania (1 dla malejącego, 0 dla rosnącego)
  300. */
  301. {
  302. {
  303. int N, k;
  304. List * A=NULL;
  305. List * B=NULL;
  306. N = List_Count(*p_list);
  307. if (N > 1)
  308. {
  309. k = N / 2;
  310. A=List_GetRange(*p_list, 0, k);
  311. B=List_GetRange(*p_list, k, N-k);
  312. A=List_MergeSort(&A, sort_direction);
  313. B=List_MergeSort(&B, sort_direction);
  314. List_Del_All(p_list);
  315. List_Merge(&A, &B, sort_direction);
  316. return A;
  317. }
  318. else
  319. {
  320. return *p_list;
  321. }
  322.  
  323. }
  324. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement