常用的8种排序算法总结
2017-03-22 11:18
239 查看
常用的8种排序算法总结
平台:VS2013编程语言: c/c++
1. 桶排序
简单桶排序算法的核心思想为将每一个数字作为桶的编号,如果在序列中有该数字便放入该桶中,因此算法的时间复杂度为O(n), 但空间复杂度很大,浪费了很多空间。具体代码如下://c/c++ //bucketSort void bucketSort(vector<int>& vNum){ map<int, int> mNum;//使用map作为桶可以有效减少空间的浪费 for (auto i : vNum) mNum[i]++; vector<int> vTmp; for (auto it = mNum.begin(); it != mNum.end(); ++it){ while (it->second--){ vTmp.push_back(it->first); } } vNum = vTmp; }
2. 冒泡排序
冒泡排序的核心思想为遍历整个数组,将一个数字逐次地与整个序列进行比较,如果发现该数小于(或大于)序列中的数,便对两数字进行交换,该数遍历完毕,则进行下一个数字的遍历,直到将所有的数字遍历完毕。因此其时间复杂度为O(n^2),空间复杂度为O(n),代码如下://c/c++ //bubble sort void bubbleSort(vector<int>& vNum){ for (int i = 0; i < vNum.size(); ++i){ for (int j = 1 + i; j < vNum.size(); ++j){ if (vNum[j] < vNum[i]){ int tmp = vNum[i]; vNum[i] = vNum[j]; vNum[j] = tmp; } } } }
3. 选择排序
选择的排序的中心思想为依次选择序列中的数字作为key,然后遍历剩下的数字,如果发现该数小于key便记录下该数的位置,遍历完毕后,将key与最小位置的数进行交换。则其时间复杂度为O(n^2),空间复杂度为O(n),其源码如下//c/c++ //choose sort void chooseSort(vector<int>& vNum){ for (int i = 0; i < vNum.size(); ++i){ int key = i; for (int j = i + 1; j < vNum.size(); ++j){ if (vNum[j] < vNum[key]) key = j; } if (key != i){ int tmp = vNum[i]; vNum[i] = vNum[key]; vNum[key] = tmp; } } }
4. 直接插入排序
直接插入排序的核心思想为在序列中选择一个数,直接与其前面的一个个进行比较,如小于前面的则将原序列中的数字后移一位,直到最后将所有的数遍历完成,直接插入排序的时间复杂度为O(n^2),其空间复杂度为O(N),其源码如下//c/c++ //insert sort void insertSort(vector<int>& vNum){ for (int i = 1; i < vNum.size(); ++i){ int key = vNum.at(i); int j = i - 1; for (j = i - 1; j >= 0; --j){ if (vNum.at(j) > key){ vNum[j + 1] = vNum[j]; } else break; } vNum[j + 1] = key; } }
5. 希尔排序
希尔排序属于插入排序算法,直接插入算法的间距为1,而希尔排序的算法间距时变化的,希尔排序的中心思想,取一个间距k, 一般取 k = n/3,其中n为序列长度。然后在序列中进行循环,每一次循环更新一次k=k/3;直到k为0。则其时间复杂度为O(N^1.5), 要比以上的好一些。其代码如下c/c++ //shell sort void shellSort(vector<int>& vNum){ int k = (vNum.size() / 3) + 1; while (k){ for (int i = k; i < vNum.size(); ++i){ int key = vNum.at(i); int j = i - k; for (j = i - k; j >= 0; j -= k){ if (key < vNum.at(j)) vNum[j + k] = vNum[j]; else break; } vNum[j + k] = key; } k /= 3; } }
6. 快速排序
快速排序的核心思想为:二分法。先选定一个数字作为key,然后遍历序列,将大于key的放在key右边,小于key的放在key左面,然后分别对左右两边序列进行相应的处理算法,直到每个序列中只有一个数字。其时间复杂度为O(NlogN)。其源码如下//c/c++ //quick sort: [low, high] void quickSort(vector<int>& vNum, int low, int high){ if (low >= high) return; else{ int mid = low; int key = vNum.at(low); int left = low + 1; int right = high; while (left < right){ if (vNum[left] > key && vNum[right] < key){ int t = vNum[left]; vNum[left] = vNum[right]; vNum[right] = t; } else{ if (vNum[left] <= key) ++left; if (vNum[right] >= key) --right; } } if (vNum[left] < key){ int t = vNum[left]; vNum[left] = key; vNum[low] = t; mid = left; } else{ int t = vNum[left - 1]; vNum[left - 1] = key; vNum[low] = t; mid = left - 1; } quickSort(vNum, low, mid - 1); quickSort(vNum, mid + 1, high); } }
7. 归并排序
归并排序的核心思想为不断将序列二分往下递归,然后在不断将两个序列进行比较往上递归。其时间复杂度为O(NlonN),其源码如下//merge sort:[low, high] void merge(vector<int>& vNum, int low, int mid, int high){ int i = low; int j = mid + 1; vector<int> vNumTmp; while (i <= mid && j <= high){ if (vNum[i] < vNum[j])vNumTmp.push_back(vNum[i++]); else vNumTmp.push_back(vNum[j++]); } ///////////////////////////////////////////////// while (i <= mid) vNumTmp.push_back(vNum[i++]); while (j <= high)vNumTmp.push_back(vNum[j++]); /////////////////////////////////////////////// for (int i = 0; i < vNumTmp.size(); ++i) vNum[i + low] = vNumTmp[i]; } void mergeSort(vector<int >& vNum, int low, int high){ if (low >= high) return; else{ int mid = (low + high) / 2; mergeSort(vNum, low, mid); mergeSort(vNum, mid + 1, high); merge(vNum, low, mid, high); } }
8. 堆排序
堆排序其实就是在完全二叉树的基础上,进行求解最大数。每一次求解后,在重新寻找,其时间按复杂度为O(NlonN)。其源码如下//heap sort int maxHeap(vector<int>& vNum){ int l = log2(vNum.size()); for (int i = l; i >= 0; --i ){ for (int j = pow(2, i); j < pow(2, i + 1); ++j){ if (2 * j<vNum.size() && vNum[2 * j]>vNum[j]){ int tmp = vNum.at(2 * j); vNum[2 * j] = vNum[j]; vNum[j] = tmp; } if (2 * j+1<vNum.size() && vNum[2 * j+1]>vNum[j]){ int tmp = vNum.at(2 * j+1); vNum[2 * j+1] = vNum[j]; vNum[j] = tmp; } } } return vNum[1]; } void heapSort(vector<int>& vNum){ vector<int> vTmp; int t; while (vNum.size()>1){ t = maxHeap(vNum); vNum.erase(vNum.begin()+1, vNum.begin() + 2); vTmp.push_back(t); } vNum = vTmp; }
相关文章推荐
- 常用的8种排序算法总结
- 八种常用排序算法总结
- 8种经典排序算法总结
- 常用排序算法总结---Java实现
- 几种常用排序算法总结(转载)
- 算法与数据结构-常用排序算法总结1-比较排序
- 常用排序算法总结4一一归并排序
- 时间复杂度为O(N*logN)的常用排序算法总结与Java实现
- 常用的排序算法总结
- 总结一些常用的排序算法,备忘
- 常用排序算法总结
- 常用计算机排序算法简单总结
- 几种常用的排序算法总结
- 总结:编程中常用的排序算法
- 【学习总结】Java中最常用的三大排序算法-冒泡排序、选择排序、插入排序
- 常用排序算法总结
- Python实现常用排序算法总结
- 几种常用排序算法总结
- 几种常用排序算法总结
- 8种经典排序算法总结