我的所有的排序算法都写在一个cpp文件里面了,所以日记也不分开每种都介绍了。
排序只要分为: 基于关键字比较的:插入排序(直接插入排序和希尔排序),交换排序(冒泡和快速排序),选择排序(直接选择和堆排序),合并排序等。 不基于关键字比较的:分布排序。 其中,广泛应用的是快速排序。 几种排序算法是:直接插入,选择插入排序,冒泡排序,希尔排序,快速排序(递归和不递归的),二路归并排序,堆排序,基数排序,分布排序 用到的一些头文件,以后再传。主要是几种数据结构链表队列栈二叉树等等的类 写得不好的或者有错误的请指正了,感激不尽……… -------------------------头文件 const int MaxNum = 8;//大于八位不支持,用于基数排序 class Element { public: int GetKey() const {return key;} void SetKey(int k) {key = k;} //------基数排序专用 int GetKey(int n) ;//返回某位的数值eg :120返回GetKey(1) = 1; void SetKey(int k, int n); //设置某位的数值 //设置所有的数值,number表示位数,默认radix为10吧-- void SetKeyB(int key, const int number) { const int radix = 10; int power = 0; int j = 0; //最后一位先不进行计算 for (int i = 1; i < number; i ++) { for (j = 1; j <= number-i; j ++) { power *= radix; } keys[i] = key/power; keys[i] = keys[i]%radix; } //设置最后一位 keys[i] = keys[i]%radix; for (int k = i + 1; k < MaxNum+1; k++) keys[k] = 0; } private: int key; public: //-------基数排序专用 int link; //用于基数排序,指向下一个元素 int keys[MaxNum+1] ;//关键字的位数,基数排序只针对整数 =。= }; -------------------------cpp文件 #include "Sort.h" #include "LStack.h" const int k0 = 0; const int M = 8; //大于M采用快速排序 小于M采用插入排序 void Interchange(Element *list, int m, int n) { Element temp; temp = list[m]; list[m] = list[n]; list[n] = temp; } //直接插入排序 k0为最小值 void InsertSortA(Element *list, int n) { Element e; int i; list[0].SetKey(k0); for (int j = 2; j <= n; j++) { e = list[j]; i = j-1; while(e.GetKey() < list[i].GetKey()) { list[i+1] = list[i]; i --; } list[i+1] = e; } } //冒泡排序 void Bubble(Element *R, int n) { int bound, j, t; Element e; bound = n; while(bound) { t = 0; for(j = 1; j < bound; j++) if (R[j].GetKey() > R[j+1].GetKey()) { e = R[j]; R[j] = R[j+1]; R[j+1] = e; } t = j; bound = t; } } //直接选择排序 void SSort(Element *R, int n) { int t; Element e; for (int j = n; j >= 2; j--) { t = 1; for (int i = 2; i <= j; i ++) { if (R[t].GetKey() < R[i].GetKey()) t = i; } e = R[t]; R[t] = R[j]; R[j] = e; } } //shell排序 void ShellSort(Element *list, int n) { int gap = n; int i; Element e; int t; while(gap >= 1) { gap = gap/2; for(i = 1; i <= gap; i ++) { for(int j = i+gap; j <= n; j = j+gap) { e = list[j]; t = j - gap; while(e.GetKey() < list[t].GetKey()) { list[t+gap] = list[t]; t = t - gap; if (t <= i) break; } } list[t+gap] = e; } } } //二路归并算法sourcelist[t...m]和sourcelist[m+1.....n]都已经排序好,把他们合并到mergedlist[t...n] void merge(Element *sourcelist, Element *mergedlist, const int t, const int m, const int n) { int i, j, k; i = t; j = m+1; k = t; while(i <= m && j <= n) { if (sourcelist[i].GetKey() <= sourcelist[j].GetKey()) { mergedlist[k] = sourcelist[i]; i ++; } else { mergedlist[k] = sourcelist[j]; j ++; } k ++; } if (i > m) { for(int p = k; p <= n; p++) mergedlist[p] = sourcelist[j+p-k]; } else { for(int p = k; p <= n; p++) mergedlist[p] = sourcelist[i+p-k]; } } //一趟合并算法 void MPass(Element *sourcelist, Element *mergedlist, const int n, int length) { for (int j = 1; j <= n-2*length+1; j += 2*length) merge(sourcelist, mergedlist, j, j+length-1, j+2*length-1); if (j+length < n) merge(sourcelist, mergedlist, j, j+length-1, n); else for(int p = j; p <= n; p ++) mergedlist[p] = sourcelist[p]; } //直接二路合并算法 void Msort(Element *list, const int n) { Element *templist = new Element[n+1]; for (int j = 1; j < n; j *= 2) { MPass(list, templist, n ,j); j *= 2; MPass(templist, list, n, j); } delete [] templist; } //快速排序的递归算法,第m个位置的关键字作为分划的关键字k //R[m...n]对进行排序 void QSort(Element *R, int m, int n) { int i, j, k, temp; if (m < n) { i = m; j = n + 1; k = R[m].GetKey(); while(i < j) { i ++; while(R[i].GetKey() < k) i++; j --; while(R[j].GetKey() > k) j--; if (i < j) { temp = R[i].GetKey(); R[i].SetKey(R[j].GetKey()); R[j].SetKey(temp); } } temp = R[m].GetKey(); R[m].SetKey(R[j].GetKey()); R[j].SetKey(temp); QSort(R, m, j-1); QSort(R, j+1, n); } } //分划方法,取位置的中间值,相当于设置QSort(Element *R, int m, int n)的m值 int Part(Element *list, int m, int n) { int i, j, k; Interchange(list, (int)(m+n)/2, m+1); if (list[m+1].GetKey() > list[n].GetKey())Interchange(list, m+1, n); if (list[m].GetKey() > list[n].GetKey())Interchange(list, m, n); if (list[m+1].GetKey() > list[m].GetKey())Interchange(list, m+1, m); i = m; j = n+1; k = list[m].GetKey(); while(i < j) { i ++; while(list[i].GetKey() < k) i ++; j--; while(list[j].GetKey() > k) j --; if (i < j)Interchange(list, i, j); } Interchange(list, m, j); return j; } //快速排序的非递归算法 struct stacktype { int x; int y; }; void HSort(int n, Element *R, int M) { LStack<stacktype> stackptr; stacktype temp; int f, t, j; temp.x = temp.y = 0; stackptr.Push(temp); f = 1; t = n; while (f < t) { j = Part(R, f, t); if ((j-f < M) && (t-j < M)) { stackptr.Pop(temp); f = temp.x; t = temp.y; continue; } if ((j-f < M) && (t-j >= M)) { f = j + 1; continue; } if ((j-f >= M) && (t-j < M)) { t = j - 1; continue; } if ((j-f >= M) && (t-j >= M)) { if (j-f > t-j) { temp.x = f; temp.y = j - 1; stackptr.Push(temp); f = j + 1; } else { temp.x = j + 1; temp.y = t; stackptr.Push(temp); t = j - 1; } } } InsertSortA(R, n); } //重建堆tree[root]的二叉树,结点个数为n void Restore(Element *tree, int root, const int n) { int m; int j = root; while(j <= (int)(n/2)) { if ((2*j < n) && (tree[2*j].GetKey() < tree[2*j + 1].GetKey())) m = 2*j + 1; else m = 2 * j; //父节点关键值小于孩子结点的关键值 if (tree[j].GetKey() < tree[m].GetKey()) { //将孩子结点关键值大的交换到父节点 Interchange(tree, j, m); j = m; } else j = n; } } //堆排序R[1...n] void HeapSor(Element *R, const int n) { int i; for(i = n/2; i >= 1; i--) Restore(R, i, n); for (i = n; i > 1; i--) { Interchange(R, 1, i); Restore(R, 1, i-1); } } //基数排序 //radix为基数 p个关键字的位数key[0...p-1] n个待排序列list[1...n] void RadixSort(Element *list, const int n, const int p, const int radix) { //指向表示桶的每个队列的队头和队尾 int *start = new int[radix]; int *end = new int[radix]; //建立初始链表 for (int j = 1; j < n; j ++)list[j].link = j + 1; list[n].link = 0; int current = 1; int k = 0; int last; //从低位开始依次按子关键词key[i]排序 for (int i = p-1; i >= 0; i--) { //初始化队列表头 for (j = 0; j < radix; j++)start[j] = 0; while(current) { k = list[current].GetKey(i); if (!start[k]) start[k] = current; else list[end[k]].link = current; end[k] = current; current = list[current].link; } //寻找第一个非空队列 for (j = 0; start[j] == 0; j++); current = start[j]; last = end[j]; for(int k = j+1; k < radix; k++) { if (start[k]) { list[last].link = start[k]; last = end[k]; } } list[last].link = 0; } delete [] start; delete [] end; } //分布计数排序算法,count[i]为相应位置的大小 //对R[1...n]文件进行排序 关键字:最小值指是u,最大值是v void Distribute(Element *R, Element *S, const int n, const int u, const int v) { int i, j; int *count = new int[v-u+1]; for (i = u; i <= v; i++) count[i-u] = 0; for (j = 1; j <= n; j++)count[R[j].GetKey()-u]++; for (i = u+1; i <= v; i++)count[i-u] += count[i-u-1]; for (j = n; j >= 1; j --) { i = count[R[j].GetKey()-u]; S[i] = R[j]; count[R[j].GetKey()-u] --; } delete [] count; } |