No.7.堆排序之python实现

一、什么是堆
python常见数据结构的时间复杂度总结
用一幅图来表示它的演变过程吧(大顶堆)
在这里插入图片描述
如下图所示即为堆
在这里插入图片描述
在这里插入图片描述
大顶堆实现代码如下

def heapify(tree, tree_len, current_node):  # 当前做heapify的节点一下的所有结点已经构成了堆的结构
    left, right = current_node * 2 + 1, current_node * 2 + 2  # left为左节点的下标,right为右节点的下标
    if current_node >= tree_len:
        return
    max_node = current_node
    if left < tree_len and tree[left] > tree[max_node]:
        max_node = left
    if right < tree_len and tree[right] > tree[max_node]:
        max_node = right
    if max_node != current_node:
        tree[max_node], tree[current_node] = tree[current_node], tree[max_node]
        heapify(tree, tree_len, max_node)


def sort_heap(tree, tree_len):
    last_node = tree_len - 1
    parend_node = (last_node - 1) // 2
    for i in range(parend_node, -1, -1):  # 将一个凌乱的完全二叉树造为堆
        heapify(tree, tree_len, i)
    for j in range(tree_len - 1, -1, -1):  # 对堆进行排序
        tree[j], tree[0] = tree[0], tree[j]
        heapify(tree, j, 0)


test = [2, 5, 3, 1, 10, 4]
sort_heap(test, len(test))
print(test)

运行结果如下
在这里插入图片描述
小顶堆的话只需将大顶堆中的

def heapify(tree, tree_len, current_node):  # 当前做heapify的节点一下的所有结点已经构成了堆的结构
    left, right = current_node * 2 + 1, current_node * 2 + 2  # left为左节点的下标,right为右节点的下标
    if current_node >= tree_len:
        return
    max_node = current_node
    if left < tree_len and tree[left] < tree[max_node]:
        max_node = left
    if right < tree_len and tree[right] < tree[max_node]:
        max_node = right
    if max_node != current_node:
        tree[max_node], tree[current_node] = tree[current_node], tree[max_node]
        heapify(tree, tree_len, max_node)

在这里插入图片描述
c语言版(大顶堆)

#include <stdio.h>
#include <stdlib.h>

void swap(int *arr,int i, int k) 
{
    int temp = arr[i];
    arr[i] = arr[k];
    arr[k] = temp;
}


void max_heapify(int *arr, int start, int end) 
{
    //建立父节点下标和子节点下标
    int dad = start;

    int son = dad * 2 + 1;

    while (son <= end) 
    {   //若子节点下标在范围内才做比较
        if (son + 1 <= end && arr[son] < arr[son + 1]) //先比较两个子节点大小,选择最大的
        {
            son++;
        
        }

        if (arr[dad] > arr[son]) //如果父节点大于子节点代表调整完毕,直接跳出
        {
            return;
        }   
        else 
        {   //否则交换父子节点的值再继续左右子节点值得比较
            swap(arr,dad, son);
            printf("dad=%d--son=%d\n",dad,son);
            dad = son;
            son = dad * 2 + 1;
        }
            
    }
}

void heap_sort(int *arr, int len) 
{
    int i;
    //初始化,i从最后一个父节点开始调整
    for (i = len / 2 - 1; i >= 0; i--)
    {
        max_heapify(arr, i, len - 1);
        
    }


    for (i = len - 1; i > 0; i--) 
    {
        swap(arr,0, i);

        max_heapify(arr, 0, i - 1);
    }
}

int main(int argc, char const *argv[])
{
    int arr[] = {5,3,8,1,6};

    int len = sizeof(arr) / sizeof(int);

    heap_sort(arr, len);

    for (int i = 0; i < len; i++)
    {
        printf("%d ", arr[i]);
    }
        
    printf("\n");
    
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值