排序算法总结
一、排序中的思想方法
1.分治
快速排序
归并排序
基数排序
2.变无序为有序,使用某种数据结构对数据进行预处理(即将数据按一定规则组织起来,方便高效地排序)
二叉排序树
堆排序
Trie
3.将几种思想方法进行综合
希尔排序:先处理使其基本有序,在使用插入排序其效率就会提升很多
4.从简单处(初始处,特殊处,易确定处)着手,一步步由简单解构造出全局的复杂的解
选择排序:每次选取最小的
5.抓住数据的根本,利用有限研究无限
基数排序:利用组成数据的十个数据:(0~9),将所有的数据分成十类,数位DP也是利用这一思想
Trie:Trie将所有单词归结为26个单词的组合,利用这一特点来统一拆分和组织数据
二、排序算法实现(主要部分)
/******************************** 直接插入排序 **********************************/ // 注意:下标从1开始 void InsertSort(SqList &L) { int i, j; for (i = 2; i <= L.length; i++) { if (L.elem[i] < L.elem[i - 1]) { L.elem[0] = L.elem[i]; for (j = i - 1; j >= 1 && L.elem[j] > L.elem[0]; j--) { L.elem[j + 1] = L.elem[j]; //写成了L.elem[j + 1] = L.elem[0]; } L.elem[j + 1] = L.elem[0]; } } } /******************************** 希尔排序 ************************************/ // 注意:下标从1开始 void ShellInsert(SqList &L, int dk) { int i, j; for (i = dk + 1; i <= L.length; i++) { if (L.elem[i] < L.elem[i - dk]) { L.elem[0] = L.elem[i]; for (j = i - dk; j >= 1 && L.elem[j] > L.elem[0]; j -= dk) { //j -= dk 写成j-- L.elem[j + dk] = L.elem[j]; } L.elem[j + dk] = L.elem[0]; } } } void ShellSort(SqList &L, int dlta[], int t) { int i; for (i = 0; i < t; i++) { ShellInsert(L, dlta[i]); } } /******************************** 快速排序 **********************************/ // 注意:下标从0开始 void Swap(int &v1, int &v2) { int tmp = v1; v1 = v2; v2 = tmp; } void QuickSort(SqList &L, int i, int j) { if (j - i + 1 <= 1) return; int p1 = i + 1, p2 = j; while (p1 < p2) { while (p1 < j && p1 < p2 && L.elem[p1] <= L.elem[i]) p1++; while (p2 > i && p2 > p1 && L.elem[p2] > L.elem[i]) p2--; Swap(L.elem[p1], L.elem[p2]); } if (L.elem[i] >= L.elem[p1]) { Swap(L.elem[i], L.elem[p1]); QuickSort(L, i, p1 - 1); QuickSort(L, p2 + 1, j); } else if (p1 - 1 > i) { Swap(L.elem[i], L.elem[p1 - 1]); QuickSort(L, i, p1 - 2); QuickSort(L, p2, j); } else { QuickSort(L, i + 1, j); } } /******************************** 归并排序 ************************************/ // 注意:下标从0开始 void Merge(SqList &L, int i, int j) { int p, q; int k = i; int m = (i + j) / 2; int M[MAX] = {0}; for (p = i, q = m + 1; p <= m && q <= j;) { //写成p <= i && q <= j if (L.elem[p] <= L.elem[q]) //写成L.elem[i++] <= L.elem[j++] M[k++] = L.elem[p++]; else M[k++] = L.elem[q++]; } while (p <= m) M[k++] = L.elem[p++]; //忘了写 while (q <= j) M[k++] = L.elem[q++]; //忘了写 for (k = i; k <= j; k++) L.elem[k] = M[k]; } void MergeSort(SqList &L, int i, int j) { if (j - i + 1 <= 1) return; int m = (i + j) / 2; MergeSort(L, i, m); MergeSort(L, m + 1, j); Merge(L, i, j); } void Distribute(int times, int n) { int i; // 初始化静态邻接表 for (i = 0; i < SL.length; i++) { SL.SLList[i].next = NULL; endp[i] = &SL.SLList[i]; } // 进行第times次分配 for (i = 0; i < n; i++) { int tmp = data[i]; tmp = (int)(tmp / pow(10, times - 1)) % 10; SLCell *p = (SLCell *)malloc(sizeof(SLCell)); if (!p) exit(1); p->data = data[i]; p->next = &SL.SLList[tmp]; if (SL.SLList[tmp].next) { //细节 SL.SLList[tmp].next->next = p; } else { endp[tmp] = p; } SL.SLList[tmp].next = p; } } void Collect() { int i; int k = 0; for (i = 0; i < SL.length; i++) { if (endp[i] != &SL.SLList[i]) { SLCell *p = endp[i]; while (p != &SL.SLList[i]) { data[k++] = p->data; p = p->next; //忘写这一句,循环里总是忘记移动指针 } } } } /******************************** 基数排序 **********************************/ // 注意:下标从0开始 void RadixSort(int n) { if (n <= 1) return; int i; int times = GetTimes(n); for (i = 1; i <= times; i++) { Distribute(i, n); Collect(); } } /******************************** 堆排序 *************************************/ void AdjustHeap(SqList &L, int length, int i) { int l = 2 * i; int r = 2 * i + 1; if (l > length && r > length) { return; } else if (r > length) { if (L.elem[i].data < L.elem[l].data) { Swap(L.elem[i], L.elem[l]); AdjustHeap(L, length, l); } } else { if (L.elem[i].data >= L.elem[l].data && L.elem[i].data >= L.elem[r].data) { ; } else if (L.elem[l].data >= L.elem[i].data && L.elem[l].data >= L.elem[r].data) { Swap(L.elem[i], L.elem[l]); AdjustHeap(L, length, l); } else { Swap(L.elem[i], L.elem[r]); AdjustHeap(L, length, r); } } } void CreateHeap(SqList &L) { int i; //建立父子关系 for (i = 1; i <= L.length / 2; i++) { L.elem[i].l = 2 * i; if (2 * i + 1 <= L.length) L.elem[i].r = 2 * i + 1; else L.elem[i].r = 0; } for (i = L.length / 2 + 1; i <= L.length; i++) { L.elem[i].l = 0; L.elem[i].r = 0; } //调整 for (i = L.length / 2; i >= 1; i--) { AdjustHeap(L, L.length, i); } } void HeapSort(SqList &L) { CreateHeap(L); for (int i = L.length; i >= 2; i--) { Swap(L.elem[i], L.elem[1]); AdjustHeap(L, i - 1, 1); } } /******************************** 二叉排序树 **********************************/ void InsertBST(BSTree &T, int data) { if (!T) { T = (BSTree)malloc(sizeof(Node)); if (!T) exit(1); T->data = data; T->num = 1; T->l = T->r = NULL; return; } if (data < T->data) { InsertBST(T->l, data); } else if (data > T->data) { InsertBST(T->r, data); } else { T->num++; return; } } void TraverseBST(BSTree T, void(*Visit)(BSTree)) { if (!T) return; TraverseBST(T->l, Visit); Visit(T); TraverseBST(T->r, Visit); } /******************************** Trie ****************************************/ //拆分数位,从高位到低位依次插入 Trie,可实现十位数及以内的整数排序 Trie Init(Trie p) { p = (Trie)malloc(sizeof(Node)); if (!p) exit(1); p->data = INFINITE; p->num = 0; p->bits = 0; for (int i = 0; i < BASE; i++) p->next[i] = NULL; return p; } void TrieInsert(Trie T, int data, int n) { if (n == 0) return; Trie p = T; int i = 0; while (i < n) { int pt = (data / base[n - 1 - i]) % 10; if (!p->next[pt]) { Trie q; p->next[pt] = Init(q); } p = p->next[pt]; i++; } if (p->num != 0) { p->num++; } else { p->data = data; p->num = 1; p->bits = n; } } void TrieTraverse(Trie T) { if (!T) return; if (T->data != INFINITE) { for (int i = 0; i < T->num; i++) { v[T->bits].push_back(T->data); } } for (int i = 0; i < BASE - 1; i++) { if (T->next[i]) TrieTraverse(T->next[i]); } }