O(lgn)的三种排序,快速排序、归并排序、堆排序
2014-05-15 20:35
218 查看
快速排序:
取某个数作为中间数来进行比较,不断的交换数组中的两个数,分成小于中间数和大于中间数的两个分组,再对分组做快速排序(也就是用递归的思想)
归并排序:
从中间把数组分成两部分,每部分都进行一次归并排序(递归),然后再使用merge把这两部分已排完序的数组合并成顺序数组。
堆排序:
1、保持堆特性:左右两子树都为最大堆,只有父节点可能不满足,于是递归的进行保持最大堆特性的运算(也就是不满足就和子树换,换完继续对子树进行保持对特性)
2、建堆:利用1中的函数,从叶子的父节点开始到根节点进行保持对特性的运算,从而达到建堆。
3、排序:由于建堆完成之后,根节点一定是最大值,因此不断的把根节点和叶子交换,并且减少数组大小。
代码附上:
取某个数作为中间数来进行比较,不断的交换数组中的两个数,分成小于中间数和大于中间数的两个分组,再对分组做快速排序(也就是用递归的思想)
归并排序:
从中间把数组分成两部分,每部分都进行一次归并排序(递归),然后再使用merge把这两部分已排完序的数组合并成顺序数组。
堆排序:
1、保持堆特性:左右两子树都为最大堆,只有父节点可能不满足,于是递归的进行保持最大堆特性的运算(也就是不满足就和子树换,换完继续对子树进行保持对特性)
2、建堆:利用1中的函数,从叶子的父节点开始到根节点进行保持对特性的运算,从而达到建堆。
3、排序:由于建堆完成之后,根节点一定是最大值,因此不断的把根节点和叶子交换,并且减少数组大小。
代码附上:
void swap(int *vec, int i, int j) { int tmp = vec[i]; vec[i] = vec[j]; vec[j] = tmp; } void quicksort(int *vec, int beg, int end) { if(beg < end) { //每次都取最后一位数当比较数; int num = vec[end]; int mid = beg; for(int i = beg; i < end; ++i) { if(vec[i] < num) { swap(vec, i, mid++); } } swap(vec, mid, end); quicksort(vec, beg, mid - 1); quicksort(vec, mid+1, end); } } void merge(int *vec, int p, int q, int end) { int n1 = q-p; int n2 = end - q + 1; int *l = new int[n1]; int *r = new int[n2]; for(int i = 0; i < n1; ++i) { l[i] = vec[p + i]; } for(int i = 0; i < n2; ++i) { r[i] = vec[q + i]; } int l_beg = 0; int r_beg = 0; for(int i = p; i <= end; ++i) { if(l_beg == n1) { while(r_beg != n2) vec[i++] = r[r_beg++]; break; } else if(r_beg == n2) { while(l_beg != n1) vec[i++] = l[l_beg++]; break; } if(l[l_beg] < r[r_beg]) vec[i] = l[l_beg++]; else vec[i] = r[r_beg++]; } } void mergesort(int *vec,int beg, int end) { if(beg < end) { int q = (beg+end)/2; mergesort(vec, beg, q); mergesort(vec, q+1, end); merge(vec, beg, q+1, end); } } //root = 0; //parent(i) = (i+1)/2-1; //left(i) = 2*i+1; //right(i) = 2*(i+1); void maxHeap(int vec[],int n, int index) { if(index * 2 + 2 <= n) { int p = vec[index]; int l = vec[index*2 + 1]; int r = vec[index*2 + 2]; int maxIndex = p >= l ? index : index*2 + 1; maxIndex = vec[maxIndex] >= r ? maxIndex : index*2 + 2; if(maxIndex != index) { swap(vec, index, maxIndex); maxHeap(vec, n, maxIndex); } } else if(index * 2 + 1 == n) { int p = vec[index]; int l = vec[index*2 + 1]; if(l > p) { swap(vec, index, index*2); } } } void buildHeap(int vec[], int n) { int beg = (n+1)/2 - 1; for(int i = beg; i >= 0; --i) { maxHeap(vec, n, i); } } void heapsort(int vec[], int n) { buildHeap(vec, n); for(int i = n; i > 0; --i) { swap(vec, 0, i); maxHeap(vec, i-1, 0); } }
相关文章推荐
- 其他三种排序:堆排序,归并排序,快速排序
- 其他三种排序:堆排序,归并排序,快速排序
- 快速排序、归并排序、堆排序三种算法性能比较
- 三种排序算法(归并排序、快速排序,堆排序)
- 内排序(插入排序、冒泡排序、选择排序、shell排序、快速排序、归并排序、堆排序)
- 冒泡排序 快速排序 选择排序 堆排序 直接插入排序 希尔排序 归并排序
- 常用排序算法——插入排序,快速排序,归并排序,堆排序,计数排序
- 各种排序算法总结----基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- Java实现快速排序、归并排序、堆排序
- 快速排序、堆排序、归并排序
- 插入排序、二分插入排序、希尔排序、选择排序、冒泡排序、鸡尾酒排序、快速排序、堆排序、归并排序
- 经典排序算法设计与分析(插入排序、冒泡排序、选择排序、shell排序、快速排序、堆排序、分配排序、基数排序、桶排序、归并排序)
- 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。
- 那些年快速排序、归并排序、堆排序的明争暗斗……
- 快速排序 归并排序 堆排序 希尔排序
- 元素排序几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 排序算法(堆排序,归并排序,快速排序、选择排序、直接插入排序)
- 经典排序算法设计与分析(插入排序、冒泡排序、选择排序、shell排序、快速排序、堆排序、分配排序、基数排序、桶排序、归并排序)
- 【更新】排序算法比较:插入排序,冒泡排序,归并排序,堆排序,快速排序,计数排序,基数排序,桶排序
- java五种内部排序(直接插入排序、希尔排序、快速排序、堆排序、归并排序)