数据结构:堆排序

堆:满足上大下小(大根堆),或下大上小的(小根堆)完全二叉树,当用一维数组存储时

父结点位置为i;

左孩子结点位置为2i + 1;

右孩子结点位置为2i + 2。

最后一个非叶结点位置为:Ln/2」- 1

初始建堆

步骤一:可按层直接填充

步骤二:将一棵普通的完全二叉树调整为堆【因为叶子节点已是堆,从最后一个非叶子节点开始调整】

堆的调整:

3号:65满足堆条件,无需调整
2号:38不满足:
     将38所在的树调整成堆
1号:49不满足:
     将49所在的树调整成堆

在这里插入图片描述
在堆调整时要先将最后一个非叶子节点38所在的树调整成堆(判断:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] )
在这里插入图片描述

还要再将49所在的树调整成堆
在这里插入图片描述

插入:再路径上进行前后比较,比较后上移

在这里插入图片描述
在这里插入图片描述

删除:

在这里插入图片描述

#include <stdio.h>
void heap_adjust(int *a, int i, int size){		/*堆调整,a为堆存储数组,i为根节点的位置,size为堆的大小*/
    int lchild = 2*i;
    int rchild = 2*i +1;
    int max = i;
    int temp; 
    if(i <= size/2) {
        if(lchild<=size && a[lchild]>a[max]){
            max = lchild;
        }
        if(rchild<=size && a[rchild]>a[max]){
            max = rchild;
        }
        if(max != i){/*如果需要调整*/
            temp = a[i];
            a[i] = a[max];
            a[max] = temp;
            heap_adjust(a, max, size);/*所以最多比较的次数是当前节点的高度-1*/
        }
    }
}
void build_bheap(int *a, int size) {			/*建堆*/
    int i;
    for(i=(size/2)-1; i >= 1; i--){
        heap_adjust(a, i, size);
    }
}




void heap_sort(int *a, int size){		/*堆排序*/
    int i;
    int temp;
    build_bheap(a, size);
    for(i=size; i >= 1; i--){
        temp = a[1];
        a[1] = a[i];
        a[i] = temp;
        heap_adjust(a, 1, i-1);
    }
}

int main(int argc, char *argv[]){
    int a[]={10,9,8,7,6,5,4,3,2,1};
    int size = 10;
    int i;
   
    heap_sort(a, size);
    for(i=1;i <= size; i++)
        printf("%d ", a[i]);
    return 0;
}

复杂度

建堆的时间O(n):

假 如 有 N 个 节 点 , 那 么 高 度 为 H = l o g N 下 取 整 + 1 , 最 后 一 层 每 个 父 节 点 最 多 只 需 要 下 调 0 次 , 倒 数 第 二 层 最 多 只 需 要 下 调 1 次 , 顶 点 最 多 需 要 下 调 H − 1 次 所 以 总 共 的 时 间 复 杂 度 为 s = 1 ∗ 2 H − 1 + 2 ∗ 2 H − 2 + . . . + ( H − 2 ) ∗ 2 1 + ( H − 1 ) ∗ 2 0 假如有N个节点,那么高度为H=logN下取整+1,\\最后一层每个父节点最多只需要下调0次,\\倒数第二层最多只需要下调1次,顶点最多需要下调H-1次\\所以总共的时间复杂度为s = 1 * 2^{H-1} + 2 * 2^{H-2} + ... + (H-2) * 2^1 + (H-1) * 2^0 NH=logN+101H1s=12H1+22H2+...+(H2)21+(H1)20

排序的时间O(nlog n)

我们知道删除一个元素的时间复杂度是O(log n),则删除n个元素:
l o g n + l o g ( n − 1 ) + … … + l o g ( n − 2 ) + l o g 1 = O ( n l o g n ) log n + log(n-1) +……+ log(n-2) + log 1=O(nlog n) logn+log(n1)++log(n2)+log1=O(nlogn)

总时间O(nlog n)-------(因为O(n)<O(nlog n))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值