改进的堆排序算法
2013-11-04 14:49
232 查看
对堆排序的改进
1.将数据初始化为大顶堆,交换第一个和最后一个元素,这里是不变的
2.重新构造大顶堆是,首先让第一个元素下降h/2的高度(h 为堆的高度)
3.下降了h/2层后判断这个元素与它的父节点谁大,如果父节点大继续下沉,下沉的结束条件为h=0
如果父节点小,表明第一个元素下沉时走过头了,然后要往回走,进行上浮操作,上浮操作是肯定能够找到第一个元素的最终位置的
4.循环n-1次程序运行完成。
实现代码如下:
1.将数据初始化为大顶堆,交换第一个和最后一个元素,这里是不变的
2.重新构造大顶堆是,首先让第一个元素下降h/2的高度(h 为堆的高度)
3.下降了h/2层后判断这个元素与它的父节点谁大,如果父节点大继续下沉,下沉的结束条件为h=0
如果父节点小,表明第一个元素下沉时走过头了,然后要往回走,进行上浮操作,上浮操作是肯定能够找到第一个元素的最终位置的
4.循环n-1次程序运行完成。
实现代码如下:
#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <math.h> /******************************************************* *首次初始化时构建大顶推 ********************************************************/ void buildheap(int a[], int n) { for(int i=n/2; i>=1; i--) { int temp = a[i]; int j = 2*i; while(j <= n) { if(j<n && a[j]<a[j+1]) { ++j; } if(temp >= a[j]) { break; } a[j/2] = a[j]; j = 2*j; } a[j/2] = temp; } int t = a ; a = a[1]; a[1] = t; } /************************************************************ *第一个元素下沉h/2层,并返回a[1]在h/2的数组下标 *************************************************************/ int getdown(int a[], int start, int deep, int n) {//头结点下沉到第d层 int i = start; int j = 2*i; int d = 0; int temp = a[start]; while(j<=n && d<=deep) { d++; if(j<n && a[j]<a[j+1]) { ++j; } a[i] = a[j]; i = j; j = 2*i; } a[i] = temp; return i; } /************************************************************* *函数功能:a[1]下沉走过头了,再往回走 *************************************************************/ void up(int a[], int start) { int temp = a[start]; int i = start; while(a[i] > a[i/2]) { a[i]=a[i/2]; i = i/2; } a[i] = temp; } /**************************************************************** *改进后的堆排序 *定义一个长度d,在顶点下沉的过程中先先下沉d,然后和父节点比较再决定 *结点是继续下沉还是上升,从而来减少比较次数 ******************************************************************/ void main() { int n; //数组的长度 printf("请输入数组的长度:\n"); scanf("%d",&n); //初始化数组 int *a = (int *)malloc((n+1)*sizeof(int)); srand(time(0)); for(int i=0; i<n+1; i++) { a[i] = rand()%100; } //输出排序前的数组 printf("\n"); printf("排序之前的数组:\n"); for(i=1; i<n+1; i++) { printf("%d\t",a[i]); } //排序 buildheap(a,n); //改进部分 int h; //堆高度减一 int count=n-1; while(count > 1) { h = (int)(log(count+1)/log(2)); int start=1; while(true) { //先下降deep层 int i = getdown(a,start,h/2,count); //判断上浮还是继续下沉 if(a[i] >= a[i/2]) {//上浮 up(a,i); int temp = a[count]; a[count] = a[1]; a[1] = temp; break; } else {//继续下沉 start = i; h = h/2; if(h <= 0 || 2*start>count) { int temp = a[count]; a[count] = a[1]; a[1] = temp; break; } } } count--; } //输出排序后的数组 printf("\n"); printf("排序后的数组:\n"); for(i=1; i<n+1; i++) { printf("%d\t",a[i]); } free(a); }
相关文章推荐
- C++ 堆排序算法的实现与改进(含笔试面试题)
- 堆排序算法(选择排序改进)
- 堆排序算法(选择排序改进)
- 堆排序算法的改进
- 业界资讯: Flash Player Incubator 改进
- 插入排序和堆排序算法
- 堆排序算法
- 顺序表应用4-2:元素位置互换之逆置算法(数据改进)
- 重写ListView实现RaidoButton重写ListView实现RaidoButton单选改进版单选改进版
- 快排改进版——插入 三分 九分 双指针综合版
- 数组判断为空的方法改进
- 跳石板(待改进)
- pstack.sh 改进版
- java流关闭改进
- list转化成json(有待改进)
- JDK1.7新特性--对try-catch代码块的改进
- Windows Azure 代码实例页得到改进
- 编程之美--游戏之乐--1.4买书问题(改进解法)
- 软件项目经理新手上路(6) - 不要进行小改进
- 通过word embedding和关联规则改进Aspect提取效果