常见排序算法(总结)
来源:互联网 发布:sql界面添加字段默认值 编辑:程序博客网 时间:2024/06/10 02:31
常见的排序算法总览
其中基数排序和基数排序都是基于桶原理的排序(其他排序方法基于比较的排序), 其空间复杂度
1 冒泡排序:
在[0, n-1]的区间内,第一个数和第二个数比较, 如果前面的数比后面大就交换顺序, 然后第二再和第三比较, 依次比较下去, 那么最大的数就会被放在最后面。然后再对[0, n-2]区间进行相同的操作。冒泡排序的迭代是从后向前的, 数组的后i个元素会被优先排序。
class BubbleSort {public: int* bubbleSort(int* A, int n) { for(int i=0;i<n;i++) {//通过这里的j=n-1-i来实现从[0,n-1]到[0, n-i]的迭 for(int j=0;j<n-1-i;j++) { if(A[j]>A[j+1]) { swap(A[j],A[j+1]); } } } return A; }};
2 选择排序:
在范围[0, n-1]上找到一个最小值, 并把它放在位置0上,然后在[1, n-1]的范围选出最小值放在位置1上,依次进行直到只剩下一个数,排序就完成了。注意选择排序的迭代是向后缩小排序范围的, 也就是前i个元素会优先排序, 着刚好与冒泡排序相反。
class SelectionSort {public: int* selectionSort(int* A, int n) { int min_index; for(int i=0;i<n;i++) { min_index = i; for(int j=i+1;j<n;j++) { min_index = A[min_index]>A[j] ? j: min_index;//不断比较直到找到最小值 } swap(A, i, min_index); } return A; } void swap(int* A, int m, int n) { int temp; temp = A[m]; A[m]=A[n]; A[n]=temp; }};
3 插入排序:
首先是位置0上的数和位置1上的数进行比较,如果位置1上的数更小就和位置0上的数进行交换, 接下来就看位置2上的数,和位置1上的数进行比较,如果位置2上的数小就和1上的数进行交换。交换之后位置1上的数再和位置0上的数进行比较,如果还是跟小,就和位置0上的数进行交换。
class InsertionSort {public: int* insertionSort(int* A, int n) { int finger; for(int i=0;i<n;i++){ finger=i; while(finger>0){ if(A[finger-1]>A[finger]){ swap(A, finger-1,finger); } finger--; } } return A; } void swap(int* A, int index1, int index2){ int temp; temp=A[index1]; A[index1]=A[index2]; A[index2]=temp; }};
4 归并排序:
让数组中的每一个数单独成为长度为1的有序区间,然后把相邻的长度为1 的有序区间进行合并得到长度为2的有序区间。 然后再把相邻有序区间进行合并,得到最大长度为4的有序区间, 直到让数组里所有的数合并为一个有序区间,排序结束。每个合并的过程可以通过两个indexes 来实现。
//归并排序的递归实现class MergeSort {public: int* mergeSort(int* A, int n) { division(A, 0, n-1); return A; } void division(int* A, int left, int right){ if(left==right){ return; } int mid = (left+right)/2; division(A, left, mid); division(A, mid+1, right); merge(A, left, mid, right); } void merge(int* A, int left, int mid, int right){ vector<int> temp(right-left+1); int l=left; int r=mid+1; int index=0;//how to make it better? more precise? while(l<=mid && r<=right){ temp[index++]=(A[l]<A[r])? A[l++]:A[r++]; } while(l<=mid){ temp[index++]=A[l++]; } while(r<=right){ temp[index++]=A[r++]; } for(int i=0;i<temp.size();i++){ A[left+i]=temp[i]; } }};
5 快速排序:
#include<stdlib.h>class QuickSort {public: int* quickSort(int* A, int n) { division(A, 0,n-1); return A; } void division(int* A, int left, int right){ if(left<right){ int rd = left+(int)(rand()%(right-left+1)); swap(A, rd, right); int mid = partition(A, left, right); division(A, left, mid); division(A, mid+1, right); } } void swap(int* A, int index1, int index2){ int temp; temp = A[index1]; A[index1]=A[index2]; A[index2]=temp; } int partition(int* A, int left, int right){ int initial = left-1; int index = left; while(index <= right){ if(A[index]<=A[right]){ swap(A, ++initial,index); } index++; } return initial; }};
6 堆排序:
先把数组建立为一个大小为n的大根堆, 堆顶是整个数组的最大值, 将堆顶元素和堆得最后一个数进行交换,然后把最大值脱离出整个堆结构,放在数组最后的位置。然后对前面n-1大小的堆,从堆顶位置进行大根堆的调整,和上一次步骤相同,分离出最大值。直到只剩下一个数,排序过程结束。
class HeapSort {public: void swap(int* A, int i, int j){ int temp = A[i]; A[i]=A[j]; A[j]=temp; } void maxHeap(int* A, int n, int init, int end){ int parent = init, child = 2*parent+1; int val=A[parent]; while(child<=end){ if(child<end && A[child]<A[child+1]) child++; if(val<A[child]){ A[parent]=A[child]; parent=child; child=2*parent +1; } else break; } A[parent] = val; } int* heapSort(int* A, int n) { for(int i=n/2-1;i>=0;i--){ maxHeap(A,n,i,n-1); } for(int i=n-1;i>0;i--){ swap(A,0,i); maxHeap(A, n,0,i-1); } return A; }};
7 希尔排序:
改良的排序算法,改变了插入排序的步长。
class ShellSort {public: void swap(int* A, int i, int j){ int temp=A[i]; A[i]=A[j]; A[j]=temp; } int* shellSort(int* A, int n) { for(int step = n/2;step>0;step = step/2){ int index = 0; //i=step for the first case for(int i = step ;i<n;i++){ index = i; while(index>0){ if((A[index]<A[index-step]) && (index-step>=0)){ swap(A,index,index-step); index = index - step; } else{ break; } } } } return A; }};
8 计数排序:
先建立排序区间内的桶,然后让排序数组里的数对应进桶,然后从最小桶开始依次倒出,倒出顺序就是排序顺序。
#include<vector>class CountingSort {public: int* countingSort(int* A, int n) { int max_ele=0, min_ele=A[0]; for(int i=0;i<n;i++){ if(A[i]>max_ele) max_ele = A[i]; if(A[i]<min_ele) min_ele = A[i]; } int len = max_ele - min_ele +1; vector<vector<int>> ans(len); for(int i=0; i<n;i++){ ans[A[i]-min_ele].push_back(A[i]); } int count = 0; for(int i = 0; i < len; i++){ if(!ans[i].empty()){ for(vector<int>::iterator itr=ans[i].begin();itr !=ans[i].end();++itr){ A[count++] = *itr; } } } return A; }};
9 基数排序:
根据个位数入桶,然后依次倒出;再根据十位数入桶,依次倒出,直到排序数组的最高位入桶并倒出后排序结束。
class RadixSort {public: int* radixSort(int* A, int n) { for(int i=0;i<=4;i++){ distribute(A, n, i); } return A; } void distribute(int* A, int n, int count){ queue<int> ans[10]; for(int i=0;i<n;i++){ int num=A[i]/pow(10,count); ans[num%10].push(A[i]); } int index =0; for(int i=0;i<10;i++){ while(!ans[i].empty()){ A[index]=ans[i].front(); ans[i].pop(); index++; } } }};
- 常见排序算法(总结)
- 常见排序算法总结
- 常见排序算法总结
- 常见排序算法总结
- 常见排序算法总结
- 常见排序算法总结
- 常见排序算法总结
- 常见排序算法总结
- 常见排序算法总结 .
- 常见排序算法总结
- 常见排序算法总结
- 常见排序算法总结
- 常见排序算法总结
- 常见排序算法总结
- 常见排序算法总结
- 常见排序算法总结
- 常见排序算法总结
- 常见排序算法总结
- C++中引用与指针的区别
- 009_GenericServlet
- Kali 2.0使用SSH进行远程登录不上的问题
- Struts2_013_ActionSupport
- python---函数()
- 常见排序算法(总结)
- codeforces 883C Downloading B++ 枚举,贪心
- 栈 基本用法 配合字母交换
- 20171105
- CentOS7 64位下MySQL5.7安装与配置(YUM)
- 静态建表(数组模拟邻接表或链式前向星)
- 008_在自己的网站中使用MarkDown【editor.md】(Java)
- Python中如何读取CSV文件
- 数据库设计之逻辑设计