基本排序算法
来源:互联网 发布:知其雄 编辑:程序博客网 时间:2024/05/07 22:17
代码:
#include <iostream>#include <vector>#include <algorithm>using namespace std;/*---------------------------改进冒泡排序------------------------------------*/// 算法复杂度O(n^2)vector<int> BubbleSort(vector<int> vec){ int length = vec.size(); bool flag = true; //避免在剩余的数已经有序的情况下做无意义的循环判断 for (int i = 0; i < length; i++) { flag = false; for (int j = length - 1; j > 0;j--) { if (vec[j] < vec[j-1]) { swap(vec[j], vec[j -1]); flag = true; //如果有数据交换,则flag为true } } } return vec;}//简单选择排序, 算法复杂度O(n^2)vector<int> SimpleSelectionSort(vector<int> vec){ int length = vec.size(); int min = 0; //保存每次找到的最小值的下标 for (int i = 0; i < length-1; i++) { min = i; for (int j = i + 1; j < length; j++) { if (vec[j] < vec[min]) { min = j; } } if (i != min) swap(vec[i], vec[min]); } return vec;}/*---------------------------简单插入排序------------------------------------*/// 算法复杂度O(n^2)vector<int> SimpleInsertSort(vector<int> vec){ int length = vec.size(); for (int i = 1, j = 0; i < length; i++) { if (vec[i] < vec[i - 1]) { int temp = vec[i]; for (j = i - 1; j >= 0 && vec[j] > temp; j--) { vec[j + 1] = vec[j]; } vec[j + 1] = temp; } } return vec;}/*---------------------------希尔排序------------------------------------*///不稳定排序,算法复杂度O(n^(3/2))vector<int> ShellSort(vector<int> vec){ int j = 0; int increment = vec.size(); do { increment = increment / 3 + 1; for (int i = increment; i < vec.size() ; i++) { if (vec[i] < vec[i - increment]) { int temp = vec[i]; for (j = i - increment; j >= 0 && temp < vec[j];j -= increment) { vec[j + increment] = vec[j]; } vec[j + increment] = temp; } } } while (increment > 1); return vec;}/*---------------------------堆排序------------------------------------*///堆排序,不稳定排序算法,时间复杂度为O(nlogn)//不适合排序序列个数较少的情况,开始建堆所需的比较次数较多void swap(vector<int> &temp, int head, int last) //交换堆顶与未经排序子序列的最后一个结点{ int tmp = temp[head]; temp[head] = temp[last]; temp[last] = tmp;}void HeapAdjust(vector<int> &vec, int low, int high){ int temp = vec[low]; for (int j = low * 2; j <= high; j *= 2) { if (j < high && vec[j] < vec[j + 1]) j++; if (temp >= vec[j]) break; vec[low] = vec[j]; low = j; } vec[low] = temp; }vector<int> HeapSort(vector<int> vec){ vector<int> temp(vec.size() + 1, 0); temp[0] = -1; for (int i = 0; i < vec.size(); i++) { temp[i + 1] = vec[i]; } //构建大根堆 for (int i = vec.size() / 2; i > 0; i--) { HeapAdjust(temp, i, vec.size()); } //堆排序 for (int i = vec.size(); i > 1; i--) { swap(temp, 1, i); HeapAdjust(temp, 1, i-1); } for (int i = 1; i < temp.size();i++) { vec[i - 1] = temp[i]; } return vec;}/*---------------------------归并排序,递归实现------------------------------------*///合并void Merge(vector<int>& subvec, int p, int mid, int q){ int a = mid - p + 1; int b = q - mid; vector<int> L(a + 1, 0); vector<int> R(b + 1, 0); for (int i = 0; i < a; i++) L[i] = subvec[p + i]; for (int j = 0; j < b; j++) R[j] = subvec[mid + j + 1]; L[a] = R[b] = INT_MAX; int i = 0, j = 0; for (int k = p; k < q + 1; k++) { if (L[i] <= R[j]) { subvec[k] = L[i]; i++; } else { subvec[k] = R[j]; j++; } }}//分解void RSort(vector<int> &subvec, int p, int q){ if (p < q) { int mid = (p + q) / 2; RSort(subvec, p, mid); RSort(subvec, mid + 1, q); Merge(subvec, p, mid, q); //合并 }}vector<int> MergeSort(vector<int> vec){ int length = vec.size(); RSort(vec,0,length-1); //分解为多个子问题求解,分治思想 return vec;}/*---------------------------归并排序,非递归实现------------------------------------*///将有序的v1[i...m]和有序的v1[m+1...n]归并到有序的v2中void Merge2(vector<int>& v1, vector<int>& v2, int i, int m, int n){ int k = 0, j = 0; for (k = i, j = m + 1; i <= m && j <= n; k++) { if (v1[i] < v1[j]) v2[k] = v1[i++]; else v2[k] = v1[j++]; } if (i <= m) { for (int t = 0; t <= m - i; t++) v2[k+t] = v1[i+t]; } if (j <= n) { for (int t = 0; t <= n-j; t++) v2[k+t] = v1[j+t]; }}//将v1中相邻长度为gap的子序列两两归并到v2中void MergeAdjacent(vector<int>& v1, vector<int>& v2, int gap, int len) { int i = 0; while (i <= len-2*gap) { Merge2(v1, v2, i, i + gap - 1, i + 2 * gap - 1); i += 2 * gap; } if (i < len - gap + 1 ) //当不够两组进行归并时,如果剩余元素超过k个元素,仍然进行归并 Merge2(v1, v2,i, i + gap - 1, len-1); else //如果剩余元素不超过k个元素时,直接复制给中间数组 { for (int j = i; j < len; j++) { v2[j] = v1[j]; } } for (i = 0; i < len; i++) v1[i] = v2[i];}vector<int> MergeSort2(vector<int> vec){ int length = vec.size(); vector<int> vec2(length, 0); int k = 1; while (k < length) { MergeAdjacent(vec, vec2, k, length); k = 2 * k; } return vec;}/*---------------------------快速排序------------------------------------*/int Partition(vector<int>& vec, int low, int high){ int pivotkey = vec[low]; //用子表中的第一个元素作为枢轴 while (low < high) { while (vec[high] >= pivotkey && low < high) high--; swap(vec[low], vec[high]); while (vec[low] <= pivotkey && low < high) low++; swap(vec[low], vec[high]); } return low;}void QSort(vector<int>& vec, int low, int high){ int pivot; if (low < high) { pivot = Partition(vec, low, high); //算出中枢值 QSort(vec, low, pivot - 1); QSort(vec, pivot + 1, high); }}vector<int> QuickSort(vector<int> vec){ int length = vec.size(); QSort(vec, 0, length - 1); return vec;}/*---------------------------计数排序------------------------------------*///算法复杂度O(n),线性时间排序算法,适合于小范围的集合的排序vector<int> CountSort(vector<int> vec){ int length = vec.size(); vector<int> result(length,0); //保存结果 int max; //保存最大值 //找出vec中的最大值 if (length > 0) { max = vec[0]; for (int i = 1; i < length; i++) { if (max < vec[i]) max = vec[i]; } } //创建保存计数的vector vector<int> temp(max + 1, 0); //保存最后结果 //vector<int> result; for (int i = 0; i < length;i++) { temp[vec[i]] += 1; } //temp[i] 包含了小于等于i的个数,以确定i的位置 for (int i = 1; i <= max;i++) { temp[i] += temp[i - 1]; } for (int j = length - 1; j >= 0;j--) { result[temp[vec[j]]-1] = vec[j]; temp[vec[j]] = temp[vec[j]] - 1; } return result;}/*---------------------------改进的计数排序------------------------------------*///与标准的相比,可以节约一些空间,vector<int> CountSort2(vector<int> vec){ int length = vec.size(); int max; //保存最大值 //找出vec中的最大值 if (length > 0) { max = vec[0]; for (int i = 1; i < length; i++) { if (max < vec[i]) max = vec[i]; } } //创建保存计数的vector vector<int> temp(max + 1, 0); for (int i = 0; i < length; i++) { temp[vec[i]] += 1; } int j = 0; for (int i = 0; i <= max; i++) { while (temp[i]--) vec[j++] = i; } return vec;}/*---------------------------基数排序------------------------------------*///算法时间复杂度O(n),具有线性的时间代价//计数排序有两种方式,LSD由数值的最右边(低位)开始,而MSD则相反,由数值的最左边开始//LSD适用于位数少的数值,如果位数多,MSD的效率更好/*MSD实现是一个递归的过程:(1)首先根据最高位的关键码K1排序,得到若干个对象组,即分到若干个桶中,每个桶中有相同的关键字(2)再分别对每个桶根据关键码K2进行排序,再根据K2的分成若干个子桶,依次类推...(3)最后把所有桶中的序列连接起来既构成了一个有序的序列*///这里实现LSD,MSD类似//获取x这个数的第d位的数字//因为LSD由数值的最右边开始的,123的第1位为3,第二位为2,...int getDigit(int x, int d){ int a[] = { 1, 1, 10, 100 }; //本例中,最大数是百位数,因此a[]中最大为100 return (x / a[d] % 10);}vector<int> RadixSortLSD(vector<int> vec){ int length = vec.size(); int d = 3; //本例中,最大的只有3位数 int count[10]; //每个桶排序 int j; int* bucket = new int[length]; //对每位进行排序 for (int k = 1; k <= d; k++) { for (int i = 0; i < 10; i++) //利用计数排序的思想用数组模拟桶 count[i] = 0; //统计各个桶中所盛数据个数 for (int i = 0; i < length; i++) { count[getDigit(vec[i], k)]++; } for (int i = 1; i < 10; i++) { count[i] += count[i - 1]; } //这时,count[i]表示第i个桶的右边界索引 for (int i = length - 1; i >= 0; i--) { j = getDigit(vec[i], k); bucket[count[j] - 1] = vec[i]; count[j]--; } //此时,count[i]为第i个桶的左边界 //将桶中的数据收集出来 for (int i = 0, j = 0; i < length; i++, j++) vec[i] = bucket[j]; } delete[] bucket; return vec;}int main(){ vector<int> array = { 9, 1, 5, 8, 3, 7, 4, 6, 2 }; vector<int> result; //冒泡排序 result = BubbleSort(array); cout << "冒泡排序后: "; for (auto it = result.begin(); it != result.end(); it++) cout << *it << " "; cout << endl << endl; //选择排序 result = SimpleSelectionSort(array); cout << "简单选择排序后: "; for (auto it = result.begin(); it != result.end(); it++) cout << *it << " "; cout << endl << endl; //插入排序 result = SimpleInsertSort(array); cout << "简单插入排序后: "; for (auto it = result.begin(); it != result.end(); it++) cout << *it << " "; cout << endl << endl; //希尔排序 result = ShellSort(array); cout << "希尔排序后: "; for (auto it = result.begin(); it != result.end(); it++) cout << *it << " "; cout << endl << endl; //堆排序 result = HeapSort(array); cout << "堆排序后: "; for (auto it = result.begin(); it != result.end(); it++) cout << *it << " "; cout << endl << endl; //归并排序,递归实现 result = MergeSort(array); cout << "(递归实现)归并排序后: "; for (auto it = result.begin(); it != result.end(); it++) cout << *it << " "; cout << endl<<endl; //归并排序,非递归实现 result = MergeSort2(array); cout << "(非递归实现)归并排序后: "; for (auto it = result.begin(); it != result.end(); it++) cout << *it << " "; cout << endl << endl; //快速排序 result = QuickSort(array); cout << "快速排序后: "; for (auto it = result.begin(); it != result.end(); it++) cout << *it << " "; cout << endl<<endl; //计数排序 result = CountSort(array); cout << "计数排序后: "; for (auto it = result.begin(); it != result.end(); it++) cout << *it << " "; cout << endl << endl; //计数排序2 result = CountSort2(array); cout << "改进的计数排序后: "; for (auto it = result.begin(); it != result.end(); it++) cout << *it << " "; cout << endl << endl; //基数排序 vector<int> array2 = { 329, 457, 657, 83, 436, 720, 355, 221, 983}; cout << "基数排序前: "; for (auto it = array2.begin(); it != array2.end(); it++) cout << *it << " "; cout << endl; result = RadixSortLSD(array2); cout << "LSD基数排序后: "; for (auto it = result.begin(); it != result.end(); it++) cout << *it << " "; cout << endl << endl; system("pause"); return 0;}
测试:
0 0
- 排序-基本排序算法
- 算法:基本排序算法
- 基本排序算法 - 基本知识点
- 排序算法基本思想
- 常用基本排序算法
- 算法记录 : 基本排序
- 基本排序算法
- 基本排序算法实现
- 基本排序算法
- 基本排序算法思想
- 基本排序算法
- 基本的排序算法
- 排序基本算法
- 基本排序算法
- 基本排序算法
- 基本排序算法总结
- 基本排序算法汇总
- 基本排序算法小结
- [leetcode] 383. Ransom Note 解题报告
- 函数参数中带省略号的用法
- JavaScript的toString()和valueOf()区别到底是什么
- 收藏表 数据库设计
- MDCC 2016中国移动开发者大会
- 基本排序算法
- 修复rpmdb损坏故障
- Ansj中文分词Java开发小记
- 杂七杂八笔记
- 《Android 开发工程师面试指南》
- bzoj1082
- 操作系统知识点汇总
- mysql把查询的结果集合并成一个字符串
- 虚拟主机运行ASP错误解决:HTTP/1.1 New Application Failed when allowSessionState is set to false in web.config