堆结构:任意的一个父节点大于其子节点。
逻辑结构:二叉树
物理结构:数组
如果从角标0开始
父节点左孩子节点:2*i+1
父节点右孩子节点:2*i+2
最后一个非叶节点:(n-1)/2
如果从角标1开始
父节点左孩子节点:2*i
父节点右孩子节点:2*i+1
最后一个非叶节点:n/2
堆排序分析:
最优时间复杂度:O(nlog2n)
最坏时间复杂度:O(nlog2n)
平均时间复杂度:O(nlog2n)
空间复杂度:O(1)
稳定性:不稳定
堆排序主要分三个函数:
1 调整成堆结构 void HeapAdjust(int *a,int i,int size);
2 构建堆 void BuildHeap(int *a,int size);
3 堆排序 void HeapSort(int *a,int size);
当角标为0,堆排序代码:
//调整堆 void HeapAdjust(int *a,int i,int size) { int lchild=2*i+1;//左孩子节点 int rchild=2*i+2; int max=i;//临时变量 //startNode->(size-1)/2:最后的一个非叶子节点 //选取大于父节点的孩子节点与父节点交换 //寻找前一个非叶子节点 if(i<=(size-1)/2)//非叶子节点 { if(lchild<=size&&a[lchild]>a[max]) { max=lchild; } if(rchild<=size&&a[rchild]>a[max]) { max=rchild; } if(max!=i) { swap(&a[i],&a[max]); HeapAdjust(a,max,size);//避免调整之后以max为父节点的子树不是堆,简称向下调整 } } }
//构建堆 void BuildHeap(int *a,int size) { int i; //从最后一个非叶节点:(size-1)/2到根节点:0 依次向前遍历 for(i=(size-1)/2;i>=0;i--) { HeapAdjust(a,i,size); } }
//堆排序 void HeapSort(int *a,int size) { int i; BuildHeap(a,size);//构建堆 for(i=size;i>=0;i--) { swap(&a[0],&a[i]); HeapAdjust(a,0,i-1);//重新调整堆节点为大顶堆,每次循环将最大值放到堆尾,然后重新构建size:i-1的堆 } }
//交换 void swap(int *a,int *b) { int temp=*a; *a=*b; *b=temp; }
原文地址:http://blog.csdn.net/arcticfoxhan/article/details/38733411