常见排序算法
来源:互联网 发布:mac怎么锁定输入法 编辑:程序博客网 时间:2024/05/16 05:08
排序算法作为常用的基本算法,今天就来总结一下各种经典排序算法,这里只贴出代码,对算法的文字描述可以在课本或其它博客上找到很多详尽的叙述,这里直接上代码而不是常见算法书上的伪代码,希望对正在努力学数据结构与算法的朋友们有帮助:
1:冒泡排序
void BubbleSort(T a[], int n){ if(NULL == a || n <= 0) return; for(int i = 0; i < n-1; i++) { bool isSwap = false; // 一次循环中没有发生交换说明已经有序 for(int j = 0; j < n-1-i; j++) { if(a[j] > a[j+1]) { // swap(a[j], a[j+1]); T temp = a[j]; a[j] = a[j+1]; a[j+1] = temp; isSwap = true; } } if(!isSwap) { return; } }}
2:插入排序
// 类似于扑克牌的安插template<class T>void InsertionSort(T *a, int n){ int in , out; for(out = 1; out < n; ++out) { T temp = a[out]; in = out; while(in > 0 && a[in-1] >= temp) { a[in] = a[in -1]; --in; } a[in] = temp; }}
3:选择排序
// 与冒泡排序算法类似,不过选择排序是每轮选最小的,对目前最小的做标记,最后才交换,将最小的放在前面void SelectionSort(int array[], const int len) // O(n*n){ if(NULL != array && len > 0) { for(int i = 0; i < len; i++) { int min = i; for(int j = i++; j< len; j++) { if(array[j] < array[min]) min = j; } swap(array, min, i); } }}
4:归并排序
#include<iostream>using namespace std;void Merge(int a[], int tmp[], int lPos, int rPos, int rEnd){ // 这里merge类似归并两个有序数组,可以参考merge two sorted array方法,减少重复的移动次数, int i, lEnd, numElements, tmpPos; lEnd = rPos - 1; tmpPos = lPos; numElements = rEnd - lPos + 1; while(lPos <= lEnd && rPos <= rEnd) { if( a[lPos] <= a[rPos] ) tmp[tmpPos++] = a[lPos++]; else tmp[tmpPos++] = a[rPos++]; } while(lPos <= lEnd) tmp[tmpPos++] = a[lPos++]; while(rPos <= rEnd) tmp[tmpPos++] = a[rPos++]; for(i = 0; i<numElements; i++, rEnd--) a[rEnd] = tmp[rEnd];}void mSort(int a[], int tmp[], int low, int high){ if(low < high && low >= 0) { int mid = (low+high)/2; mSort(a, tmp, low, mid); mSort(a, tmp, mid+1, high); Merge(a, tmp, low, mid+1, high); }}void MergeSort(int a[], int len){ int *tmp = NULL; tmp = new int[len]; if(tmp != NULL) { mSort(a, tmp, 0, len -1); delete[] tmp; }}void print(int a[], int n){ if(a != NULL && n >= 0) { for(int i = 0; i < n; i++) { cout << a[i] << ' '; } cout << endl; }}int main(){ int a[10] = {3, 2, 54,12, 2, 5,7, 9, 5, 45}; print(a, 10); MergeSort(a, 10); print(a, 10); cout << endl; return 0;}
5:快速排序
使用了三次取中的方法选取枢轴,避免了当待排序数据基本有序时退化为冒泡排序的情况:
#include <iostream>using namespace std;/*三次取中作为枢轴,避免了当排序数组有序时时间复杂度退化为O(N^2)的情况 注:STL中sort的实现当元素个数少于10个时,调用插入排序参考网站: http://blog.csdn.net/insistgogo/article/details/7785038 http://baike.baidu.com/link?url=cskKnDW-StS4kn8P_Q_n69RDxqcKcF46JNMdLcALdxWPoTsOO5ZEi-b3FKBocA3ScARIgiVx4ZuiEjXMw2qHa_*/void swap(int& a , int& b){ a=a^b; b=a^b; a=a^b; }/*函数作用:取待排序序列中low、mid、high三个位置上数据,选取他们中间的那个数据作为枢轴*/ int SelectPivotMedianOfThree(int arr[],int low,int high) { int mid = low + ((high - low) >> 1);//计算数组中间的元素的下标 //使用三数取中法选择枢轴 if (arr[mid] > arr[high])//目标: arr[mid] <= arr[high] { swap(arr[mid],arr[high]); } if (arr[low] > arr[high])//目标: arr[low] <= arr[high] { swap(arr[low],arr[high]); } if (arr[mid] > arr[low]) //目标: arr[low] >= arr[mid] { swap(arr[mid],arr[low]); } //此时,arr[mid] <= arr[low] <= arr[high] return arr[low]; //low的位置上保存这三个位置中间的值 //分割时可以直接使用low位置的元素作为枢轴,而不用改变分割函数了 }void Qsort(int a[], int low, int high){ if(a==NULL) return; // if (high - low + 1 < 10) // STL中的代码,如果元素个数比较少,使用插入排序 // { // InsertSort(arr,low,high); // return; // } SelectPivotMedianOfThree(a, low, high); if(low >= high) { return; } int first = low; int last = high; int key = a[first]; while(first < last) { while(first < last && a[last] >= key) { --last; } a[first] = a[last]; while(first < last && a[first] <= key) { ++first; } a[last] = a[first]; } a[first] = key; Qsort(a, low, first-1); Qsort(a, first+1, high);}int main(){ int a[] = {57, 68, 59, 52, 72, 28, 96, 33, 24, -90}; for(int i = 0; i < sizeof(a) / sizeof(a[0]); i++) { cout << a[i] << " "; } cout << endl; Qsort(a, 0, sizeof(a) / sizeof(a[0]) - 1); for(int i = 0; i < sizeof(a) / sizeof(a[0]); i++) { cout << a[i] << " "; } cout << endl; return 0;}
6:希尔排序
void ShellSort(int array[], int len) // O(n*n){ int i = 0; int j = 0; int k = -1; int temp = -1; int gap = len; do { gap = gap / 3 + 1; for(i=gap; i<len; i+=gap) { k = i; temp = array[k]; for(j=i-gap; (j>=0) && (array[j]>temp); j-=gap) { array[j+gap] = array[j]; k = j; } array[k] = temp; } }while( gap > 1 );}
7:堆排序
也是top-k问题的一种解法:
#include<iostream>using namespace std;void HeapAdjust(int a[], int n, int size){ int nChild = 2*n + 1; // 左孩子 int t; while(nChild < size) { if((nChild+1 < size)&&(a[nChild+1]> a[nChild])) nChild++; if(a[nChild]<a[n]) break; t = a[nChild]; a[nChild] = a[n]; a[n] = t; n = nChild; nChild = 2 * n + 1; }}/* 这里的k指的是top-k问题吗,当k为size或(size-1)时,则是纯正完整的堆排序过程; k<size-1时,则表示取数据中前k大的元素, 没有对所有的元素进行排序,仅部分排序*/void HeapSort(int a[], int size, int k) { if(NULL == a || size < 0) return; int i; for(i = size/2-1; i>=0; i--) // 这里要理解好为什么是size/2-1的逻辑 HeapAdjust(a, i, size); // 依次调整堆,其实就是建堆的过程,因此这里没有额外的建堆函数 int t; int s = size - k; while(size>s) // 依次找到最大的放置在数组的末尾 { t = a[size-1]; a[size-1] = a[0]; a[0] = t; size --; HeapAdjust(a, 0, size); }}void print(int a[], int n){ if(NULL == a || n < 0) return; for(int i=0; i< n; i++) { cout << a[i] << " "; }}int main(){ int a[16] = {2, 1, 3, 5,4, 4, 2, 6, 13, 12, 1, 10, 21, 20, 96, -1}; HeapSort(a, 16, 16); print(a, 16); // 全部进行排序 cout << endl; int b[6] = {2, 1, 3, 20, 96, -1}; HeapSort(b, 6, 3); // 取top3,数组最后三个数是前三大的 print(b, 6); cout << endl; int c[6] = {0, 12, 31, 20, 968, -1}; HeapSort(c, 6, 2); // top2 print(c, 6); cout << endl;}
参考资料:
http://blog.csdn.net/insistgogo/article/details/7785038
0 0
- 常见的排序算法
- 常见排序算法
- 常见排序算法代码
- 常见排序算法
- 常见排序算法总结
- 常见排序算法
- 常见排序算法学习
- 常见排序算法总结
- 常见的排序算法
- 常见排序算法分析
- 常见排序算法总结
- 常见排序算法
- 常见排序算法
- 常见排序算法介绍
- 常见排序算法小结
- 常见排序算法总结
- 常见经典排序算法
- 常见排序算法
- 周总结
- 【译】VisionMobile:开发者经济报告2015 Q3(二):语音选择是区域、财务和物质
- 数据库设计原则
- green vpn服务器
- Layout常用属性介绍
- 常见排序算法
- 位图法
- uva400
- 什么是PKI?
- 快速Android开发系列网络篇之Android-Async-Http
- cpp 考试算法
- iOS开发 -- 给导航栏设置统一风格(appearance)
- 用jenkins搭建android自动打包环境
- Bluetooth的子协议学习系列-HL