單鏈表形式實現排序算法。
這個快速排序主要利用遞歸調用。包含4個文件,頭文件QuickSort.h,fatal.h,庫函數QuickSort.c,測試文件TestQuickSort。
QuickSort.h
1 typedef long ElementType; 2 #ifndef _List_H//如果沒有編譯過 3 #include<stdbool.h> 4 struct Node; 5 typedef struct Node *PtrToNode; 6 typedef PtrToNode List; 7 typedef PtrToNode Position; 8 List MakeEmpty(List L); 9 void DeleteList(List L); 10 bool IsEmpty(List L); 11 bool IsLast(Position P, List L); 12 void Insert(ElementType X, List L, Position P); 13 Position Header(List L); 14 Position First(List L); 15 Position Advance(Position P); 16 ElementType Retrieve(Position P); 17 void PrintList(const List L); 18 void SwapWithNext(Position BeforeP, List L); 19 void Qsort(List L, List tail);//快速排序核心算法 20 void QuickSort(List L);//快速排序驅動程序 21 #endif // !_List_H
fatal.h
1 #include<stdio.h> 2 #include<stdlib.h> 3 #define Error(Str) FatalError(Str) 4 #define FatalError(Str) fprintf(stderr, "%s\n", Str), exit(1);
庫函數QuickSort.c
1 // 引用頭文件 2 #include "QuickSort.h" 3 #include<stdlib.h> 4 #include "fatal.h" 5 6 //結構體定義 7 struct Node 8 { 9 ElementType Element; 10 Position Next; 11 }; 12 13 //初始化鏈表 14 List MakeEmpty(List L) 15 { 16 if (L != NULL) 17 DeleteList(L);//如果鏈表非空,則刪除鏈表 18 L = malloc(sizeof(struct Node)); 19 if (L == NULL) 20 FatalError("Out of memory!"); 21 L->Next = NULL; 22 return L; 23 } 24 25 //刪除鏈表 26 void DeleteList(List L) 27 { 28 Position P, Temp; 29 P = L->Next; 30 L->Next = NULL; 31 while (P != NULL) 32 { 33 Temp = P->Next; 34 free(P); 35 P = Temp; 36 } 37 } 38 39 //判斷鏈表是否為空 40 bool IsEmpty(List L) 41 { 42 return L->Next == NULL; 43 } 44 45 //判斷當前指針P是否指向鏈表最后一個元素 46 bool IsLast(Position P, List L) 47 { 48 return P->Next == NULL; 49 } 50 51 52 53 //插入元素X到位置P后面 54 void Insert(ElementType X, List L, Position P) 55 { 56 Position TmpCell; 57 TmpCell = malloc(sizeof(struct Node)); 58 if (TmpCell == NULL) 59 FatalError("Out of Space!!!"); 60 TmpCell->Element = X; 61 TmpCell->Next = P->Next; 62 P->Next = TmpCell; 63 } 64 65 //獲取鏈表頭 66 Position Header(List L) 67 { 68 return L; 69 } 70 71 //獲取鏈表第一個元素的位置 72 Position First(List L) 73 { 74 return L->Next; 75 } 76 77 //獲取位置P的下一個位置 78 Position Advance(Position P) 79 { 80 return P->Next; 81 } 82 83 //提取位置P處結構里面的值 84 ElementType Retrieve(Position P) 85 { 86 return P->Element; 87 } 88 89 //打印鏈表 90 void PrintList(const List L) 91 { 92 Position P = Header(L); 93 if (IsEmpty(L)) 94 printf("Empty list\n"); 95 else 96 { 97 do 98 { 99 P = Advance(P); 100 printf("%d ", Retrieve(P)); 101 } while (!IsLast(P, L)); 102 printf("\n"); 103 } 104 } 105 106 107 //通過只調整指針來交換兩個相鄰的元素,BeforeP是要調換兩個元素的前一 108 //個指針 109 void SwapWithNext(Position BeforeP, List L) 110 { 111 Position P, AfterP; 112 if (BeforeP != NULL) 113 { 114 P = Advance(BeforeP); 115 if (P != NULL) 116 { 117 AfterP = Advance(P); 118 if (AfterP != NULL) 119 { 120 P->Next = AfterP->Next; 121 BeforeP->Next = AfterP; 122 AfterP->Next = P; 123 } 124 } 125 } 126 } 127 128 //快速排序核心算法 129 void Qsort(List head, List tail) 130 { 131 //將鏈表分成2、4、8。。。,我們只說明開始分成2兩條的情況 132 //將鏈表分成兩條,小於樞紐元的鏈表1,大於等於樞紐元的鏈表2,鏈表1已經有了頭結點head,鏈表2以樞紐元為頭結點mid 133 if (head->Next == tail || head->Next->Next == tail) 134 return;//如果鏈表是空或者只有一個元素,則停止循環 135 136 List mid = head->Next;//指向樞紐元的指針 137 List p = head;//指向鏈表1,最后p指向鏈表1的尾元素 138 List q = mid;//指向鏈表2,最后q指向鏈表2的尾元素 139 ElementType pivot = mid->Element;//樞紐元 140 List t = mid->Next;//探測指針,指向下一個元素,查詢是大於樞紐元還是小於樞紐元 141 142 while (t != tail)//當探測指針指向鏈表尾節點,循環結束 143 { 144 if (t->Element < pivot)//當探測指針指向的元素<樞紐元,則把該元素接到鏈表1 145 p = p->Next = t; 146 else 147 q = q->Next = t;//當探測指針指向的元素>=樞紐元,則把該元素接到鏈表2 148 t = t->Next;//不管上一個元素大小如何,都要指向下一個元素 149 } 150 //當循環完整個鏈表,然后將鏈表1和2拼接起來 151 p->Next = mid;//將小於樞紐元的鏈表1的尾節點指向樞紐元 152 q->Next = tail;//將鏈表2的尾節點指向tail 153 154 Qsort(head, mid);//對鏈表1進行同樣的循環,當滿足113行條件,則停止這個遞歸 155 Qsort(mid, tail);//對鏈表2進行同樣的循環,當滿足113行條件,則停止這個遞歸 156 //當兩個QuickSort都滿足113行時,跳出遞歸循環,程序結束 157 } 158 159 //快速排序驅動程序 160 void QuickSort(List L) 161 { 162 Qsort(L, NULL);//調用排序算法,第二個是NULL 163 }
測試文件TestQuickSort:
1 #include<stdio.h> 2 #include "QuickSort.h" 3 #include"fatal.h" 4 #include<time.h> 5 6 int main() 7 { 8 long amount; List L; Position P; 9 L = MakeEmpty(NULL);//初始化鏈表 10 P = L; 11 if (L == NULL) Error("Out of Space!!!"); 12 printf("隨機生成多少位數:"); 13 scanf_s("%d", &amount); 14 srand((unsigned)time(NULL)); 15 for (long i = 0; i < amount; i++) 16 { 17 Insert(rand() % 1000000, L, P); 18 P = Advance(P); 19 } 20 //printf("排序前的結果:"); 21 //PrintList(L); 22 QuickSort(L);//調用排序驅動程序 23 printf("排序后的結果:"); 24 PrintList(L); 25 }

