排序算法二冒泡排序和快排
2017-08-02 01:49
435 查看
冒泡排序想必大家都非常熟悉了,这里就直接贴代码了
时间复杂度为O(N*N),最好的情况下:优化后正序有序为O(n),稳定的算法。
没有优化的与原始序列的状态无关,优化后与原始序列的状态有关
快排
挖坑法
双指针法
非递归实现:
优化:
1)三数取中法
2)当区间已经划分到很小的时候可以改用插入排序
3)尾递归减少递归次数
时间复杂度为O(n*lgn),最好情况为O(n*lgn),最坏情况O(n*n),因为递归空间复杂度O(lgn)
不稳定的算法
最坏的情况下:基本有序时,退化为冒泡排序,几乎要比较N*N次,故为O(N*N)
它的应用场景是大规模的数据排序
快速排序算法的实际执行性能依赖与切分是否均衡,当正好把数组从中间”切开”时,
快速排序的实际性能最好。
切分越不均衡快速排序的实际性能就越差,
最坏情况下(第一次选取的切分元素是数组里最小的,第二次的切分元素是第二小的…)
算法的时间复杂度会退化到O(n^2)。
void BubbleSort(int array[],int len) { assert(array && len>0 ); for(int i = 0; i < len-1; ++i) { int flag = 1; for(int j = 0; j < len-1-i; ++j) { if(array[j] > array[j+1]) { swap(array[j], array[j+1]); flag = 0; } } if(flag == 1) break; } }
时间复杂度为O(N*N),最好的情况下:优化后正序有序为O(n),稳定的算法。
没有优化的与原始序列的状态无关,优化后与原始序列的状态有关
快排
挖坑法
双指针法
//paration版本一:挖坑法 int Paration(int array[], int left, int right) { int key = array[right]; while(left < right) { while((left < right)&&(array[left] <= key) ) { left++; } swap(array[left], array[right]); while((left < right) && (array[right] >= key)) { right--; } swap(array[left], array[right]); } return left; } //paration版本二:双指针法 int Paration2(int array[], int left, int right) { int key = array[right]; int pcur = left; int pre = pcur-1; while(pcur <= right) { if((array[pcur] <= key) && (++pre != pcur) ) { swap(array[pcur], array[pre]); } ++pcur; } return pre; } void QuickSort(int array[], int left ,int right) { assert(array); if(left < right) { int index = Paration2(array, left ,right); QuickSort(array, left, index-1); QuickSort(array, index+1, right); } }
非递归实现:
void QuickSort2(int array[], int left, int right) { stack<int> s; s.push(right); s.push(left); while(!s.empty()) { int left = s.top(); s.pop(); int right = s.top(); s.pop(); if(left < right) //防止下面插入index+1, inex-1越界。 { int mid = (left+right)/2; int index = Paration2(array, left, right); s.push(right); s.push(index+1); s.push(index-1); s.push(left); } } }
优化:
1)三数取中法
2)当区间已经划分到很小的时候可以改用插入排序
3)尾递归减少递归次数
//三数取中法,防止取到极端数据 int Middle(int array[], int left, int mid, int right) { if(array[left] > array[right]) { if(array[right] > array[mid]) return right; else if(array[left] > array[mid]) return mid; else return left; } else { if(array[right] < array[mid]) return right; else if(array[left] < array[mid]) return mid; else return left; } } //paration版本二:双指针法 int Paration2(int array[], int left, int right) { int mid = (left+right)/2; int pos = Middle(array, left, mid, right); swap(array[pos], array[right]); int key = array[right]; int pcur = left; int pre = pcur-1; while(pcur <= right) { if((array[pcur] <= key) && (++pre != pcur) ) { swap(array[pcur], array[pre]); } ++pcur; } return pre; } void InsertSort(int array[], int size) { for(int i = 1; i < size; ++i) { int temp = array[i]; int end = i-1; while(end>=0 && array[end] > temp) { array[end+1] = array[end]; end--; } array[end+1] = temp; } } void QuickSort(int array[], int left ,int right) { assert(array); while(right-left > 5) //使用尾部递归 { int index = Paration2(array, left ,right); QuickSort(array, left, index-1); left = index+1; } if(right-left <= 5) //当分成很小的区间时,插入排序效率更高。 { InsertSort(array+left, right-left+1); } }
时间复杂度为O(n*lgn),最好情况为O(n*lgn),最坏情况O(n*n),因为递归空间复杂度O(lgn)
不稳定的算法
最坏的情况下:基本有序时,退化为冒泡排序,几乎要比较N*N次,故为O(N*N)
它的应用场景是大规模的数据排序
快速排序算法的实际执行性能依赖与切分是否均衡,当正好把数组从中间”切开”时,
快速排序的实际性能最好。
切分越不均衡快速排序的实际性能就越差,
最坏情况下(第一次选取的切分元素是数组里最小的,第二次的切分元素是第二小的…)
算法的时间复杂度会退化到O(n^2)。
相关文章推荐
- 排序算法---选择排序&堆排序&冒泡排序
- 排序算法学习-冒泡排序
- PHP常用排序算法实例小结【基本排序,冒泡排序,快速排序,插入排序】
- 排序算法(三) 冒泡排序
- 常见的排序算法三——冒泡排序
- 排序算法(3)——冒泡排序
- 排序算法:冒泡排序
- 小学生图解排序算法:①冒泡排序
- 【排序算法】冒泡排序原理及Java实现
- 排序算法——冒泡排序
- 排序算法:冒泡排序
- 排序算法之冒泡排序
- 排序算法-冒泡排序
- 算法系列(三)排序算法上篇--冒泡排序插入排序和选择排序
- 排序算法--冒泡排序(java)
- C#的四种排序算法:冒泡排序、选择排序、插入排序和希尔排序
- C语言常用的几种排序算法代码(选择排序,冒泡排序,插入排序,快速排序)
- 排序算法之冒泡排序
- 算法_基本排序算法之冒泡排序,选择排序,插入排序和希尔排序
- PHP排序算法:冒泡排序