快速排序、堆排序、归并排序
来源:互联网 发布:云服务器搭建sql serv 编辑:程序博客网 时间:2024/05/01 19:29
常见排序有7种:冒泡排序、希尔排序、插入排序、选择排序、快速排序、堆排序、归并排序。
此处讨论后三种时间复杂度为O(NlogN)的算法。
1,快速排序
一般情况下,快速排序迭代(或递归)次数为logN,每次恒进行N次比较;最差情况下迭代N次;
Partition部分:
int Partion(int a[], int low, int high){ int i = low; int j = high; int val = a[low]; while (i < j) { while (i < j && a[j] >= val) j--; if (i < j) // 可能已经有序; a[i++] = a[j]; while (i < j && a[i] <= val) i++; if (i < j) a[j--] = a[i]; } a[i] = val; return i;}QuickSort部分:(先调用Partition找到pivot对应的实际位置idx,然后分别对左右两部分递归)
void QuickSort(int a[], int low, int high){ if (low < high) { int idx = Partition(a, low, high); QuickSort(a, low, idx-1); QuickSort(a, idx+1, high); }}附上快速排序视觉直观图:
2,归并排序
归并排序和快速排序都是基于分治法(Divide and Conquer);需要注意的是归并排序空间复杂度O(N)。
合并两有序部分MergeArray:
void MergeArray(int a[], int low, int mid, int last, int tmp[]){ int i = low; int j = mid+1; int k = 0; while (i <= mid && j <= high) { if (a[i] <= a[j]) a[k++] = a[i++]; else a[k++] = a[j++]; } while (i <= mid) a[k++] = a[i++]; while (j <= high) a[k++] = a[j++]; for (i = 0; i < k; i++) a[low+i] = tmp[i];}
MergeSort部分:
void Mergesort(int a[], int low, int high, int tmp[]){ if (low < high) { int mid = (low +high) / 2; MergeSort(a, low, mid, tmp); MergeSort(a, mid+1, high, tmp); MergeArray(a, low, mid, high, tmp); }}main函数调用:
int main(){ int n; int a[n]; scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); int *p = (int *)malloc(n * sizeof(int)); if (p == 0) return 1; MergeSort(a, 0, n-1, p); //调用MergeSort排序 free(p); return 0;}继续附上归并排序视觉直观图:
3,堆排序
作为一种数据结构,此处将堆设为一个类,含有的建堆、插入、删除作为方法封装于类中。
(int 类型的最小堆)
class MinHeap {public: MinHeap( int maxSize );//根据最大长度建堆MinHeap( int arr[], int n); ~MinHeap( ) { delete [] heap; }const MinHeap& operator=( const MinHeap &R );//重载赋值运算符 int Insert(int x );int RemoveMin(int x );//移除关键码最小的元素,并赋给xbool IsEmpty( ) const { return CurrentSize == 0; } int IsFull( ) const { return CurrentSize == MaxHeapSize; } void MakeEmpty( ) { CurrentSize = 0; }//使堆空private: enum { DefaultSize = 50 };//默认堆的大小 int *heap; int CurrentSize; int MaxHeapSize; void FilterDown ( int i, int m ); //自上向下调整堆 void FilterUp ( int i ); //自下向上调整堆};MinHeap::MinHeap ( int maxSize ){ MaxHeapSize = (DefaultSize < maxSize ) ? maxSize : DefaultSize; heap = new int[MaxHeapSize]; CurrentSize = 0; }MinHeap::MinHeap (int arr[], int n ){ MaxHeapSize = DefaultSize < n ? n : DefaultSize; heap = new int[MaxHeapSize]; if(heap==NULL){cerr <<"fail" <<endl;exit(1);} for(int i =0; i< n; i++) heap[i] = arr[i]; //数组传送 CurrentSize = n; //当前堆大小 int currentPos = (CurrentSize-2)/2; //最后非叶 while ( currentPos >= 0 ) { FilterDown ( currentPos, CurrentSize-1 );currentPos-- ; }}void MinHeap::FilterDown (int start,int EndOfHeap ){ int i = start, j = 2*i+1; // j 是 i 的左子女 int temp = heap[i]; while ( j <= EndOfHeap ) { if ( j < EndOfHeap && heap[j] > heap[j+1] ) j++; //两子女中选小者 if ( temp<= heap[j] ) break; else { heap[i] = heap[j]; i = j; j = 2*j+1; } } heap[i] = temp;}int MinHeap::Insert (int x ) { if ( CurrentSize == MaxHeapSize ) //堆满 { cout << "堆已满" << endl; return 0; } heap[CurrentSize] = x; FilterUp (CurrentSize); //向上调整为堆 CurrentSize++; return 1;}void MinHeap::FilterUp (int start ) {int j = start; int i = (j-1) / 2; int temp = head[start]; while (i < 0) { if (head[i] < temp) break; else { head[j] = head[i]; j = i; i = (i-1) / 2; } } head[j] = temp;}int MinHeap::RemoveMin(int x){ if(CurrentSize == 0) { cout << "栈已空" << endl; return 1; } x = heap[0]; heap[0] = heap[CurrentSize - 1]; CurrentSize--; FilterDown(0, CurrentSize-1); return 0;}对数组排序即是调用MinHeap的含参构造函数MinHeap(int arr[], int n),过程为arr[]先对heap[]赋值,然后从第一个分支节点(CurrentSize-2)/2 到根节点进行FilterDown,时间复杂度O(NlogN);
Insert操作:将待插入元素x存入heap[CurrentSize], 从CurrentSize向上进行1次FilterUp,时间复杂度O(logN);
Remove操作:删除根元素(最小值),将heap[0]与heap[CurrentSize-1]对调,从根节点向下进行1次FilterDown, 时间复杂度O(logN);
文章内容由http://www.nowamagic.net/librarys/veda/detail/294 、 http://blog.csdn.net/morewindows/article/details/6709644 整理得到!
0 0
- 快速排序、堆排序、归并排序
- 快速排序、堆排序、归并排序
- 快速排序、归并排序、堆排序
- 快速排序、堆排序、归并排序
- 快速排序、堆排序、归并排序
- 归并排序、快速排序、堆排序
- 堆排序、归并排序、快速排序总结
- 归并排序、堆排序、快速排序
- 插入排序、希尔排序、堆排序、归并排序、快速排序
- 排序之选择排序、堆排序、归并排序、快速排序
- 排序(希尔排序,堆排序,归并排序,快速排序)
- 快速排序,归并,堆 ,STL
- 排序算法:希尔、归并、快速、堆排序
- 排序算法:希尔、归并、快速、堆排序
- 排序:插入,希尔,堆,快速,归并排序
- 排序算法(二):快速,归并,堆排序
- 三大排序算法(快速排序,归并排序,堆排序)
- 插入排序,快速排序,堆排序,归并排序
- Spring MVC 4常用的那些注解
- Change Yii 2.0 Default Controller
- RADASM中使用DOSBOX来运行DOS/BIOS程序(16位)
- 大数据并发问题
- mysql中的触发器
- 快速排序、堆排序、归并排序
- RabbitMQ
- 浅析Java中Map与HashMap,Hashtable,HashSet的区别
- 开始学习深度学习和循环神经网络Some starting points for deep learning and RNNs
- OpenCV--SVM多分类问题
- WaitForSingleObject函数的使用
- FMDB
- c++作业2-分段函数求值,两点距离,模拟ATM
- android 关于跳转系统设置页面