单链表形式实现排序算法。
这个快速排序主要利用递归调用。包含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 }