堆排序(非递归版)-- c语言实现
2015-08-15 09:39
375 查看
堆,是在逻辑上模仿完全二叉树的一维数组,(假设数组开始下标为0)某父节点 i 其左右孩子可以表示为2*i+1(左)和2*i+2(右).
堆排序的思想是每次从堆顶拿出一个元素(最大或最小取决于是大顶堆还是小顶堆)放入已排序数组,然后将堆最后一个元素插入堆顶,
这样将引起堆的不平衡,然后重新调整堆至平衡,重复做下去。注意,每次拿出堆顶元素堆的大小都会减小1.
关于堆的复杂度:
堆排序的思想是每次从堆顶拿出一个元素(最大或最小取决于是大顶堆还是小顶堆)放入已排序数组,然后将堆最后一个元素插入堆顶,
这样将引起堆的不平衡,然后重新调整堆至平衡,重复做下去。注意,每次拿出堆顶元素堆的大小都会减小1.
关于堆的复杂度:
排序算法 | 平均时间复杂度 | 最坏时间复杂度 | 最好时间复杂度 | 空间复杂度 | 稳定性 | 复杂性 |
堆排序 | O(nlgn) | O(nlgn) | O(nlgn) | O(1) | 不稳定 | 较复杂 |
#include <stdio.h> #include <stdlib.h> #define size 10 /*数组大小*/ #define lchild(i) (2*i+1) /*数组起始下标为0,其左孩子为2*i+1 */ #define swap(a,b) {a^=b;b^=a;a^=b;} /*两个元素交换*/ /*调整堆平衡的函数*/ void heap_adjust(int *arr,int start,int end) { int temp = arr[start]; int i; for(i = lchild(start); i <= end; i*=2){ /*获得两个孩子中较大的一个,如果右孩子大于左孩子,则 *i下标增加为右孩子下标,否则不变 */ if(i<end && arr[i]<arr[i+1]){ i++; } /*比较父亲和孩子中较大的*/ if(temp > arr[i]){ break; } /*孩子比父亲大,孩子上位取代父亲*/ arr[start] = arr[i]; /*以孩子的位置进行下一次调整*/ start = i; } /*插入最开始引起堆不平衡的元素*/ arr[start] = temp; } /*堆排序主程序*/ void heap_sort(int *arr,int n) { int i; /*创建大顶堆,从最后一个非叶子节点开始,自 *下而上调整。 */ for(i = n/2;i>=0;i--){ heap_adjust(arr,i,n-1); } /*堆排序。每次将堆顶元素与堆的最后一个叶子节点交换 *交换后堆不平衡,重新调整堆,每交换一次,要调整堆 *的大小减小一个 */ for(i=n -1;i > 0;i--){ swap(arr[0],arr[i]); heap_adjust(arr,0,i-1); } } int main() { int arr[size]={1,3,4,7,13,-1,8,2,6,0}; heap_sort(arr,size); int i; for(i = 0;i<size;i++){ printf("%d ",arr[i]); } return 0; }
相关文章推荐
- JavaScript演示排序算法
- 算法之排序算法的算法思想和使用场景总结
- php 地区分类排序算法
- js三种排序算法分享
- Javascript中的常见排序算法
- java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序算法的描述
- 排序算法的javascript实现与讲解(99js手记)
- C++中十种内部排序算法的比较分析
- Java实现几种常见排序算法代码
- 浅谈javascript实现八大排序
- PHP常用的排序和查找算法
- JavaScript中九种常用排序算法
- STl中的排序算法详细解析
- PHP四种基本排序算法示例
- 排序算法之PHP版快速排序、冒泡排序
- JavaScript排序算法之希尔排序的2个实例
- Java常用排序算法及性能测试集合
- Java中常用的6种排序算法详细分解
- Javascript排序算法之合并排序(归并排序)的2个例子
- JAVA简单选择排序算法原理及实现