堆排序的实现(递归与非递归)

堆排序实质就是选择排序的优化版,将选择排序的选择部分优化成logn。

思路:

由小到大堆排序首先要构造大顶堆(父节点的值大于子节点的值)

再依次交换最后一个节点的值,已经排好的不用管

再对第一个结点进行构造大顶堆的操作

重复进行如上操作便排序完成

非递归版本

#include <stdio.h>
#include <stdlib.h>
void swap(int tree[],int a,int b)
{
    int temp=tree[a];
    tree[a]=tree[b];
    tree[b]=temp;
}//交换函数

void heap_sort(int tree[],int n)
{
    build_tree(tree,n);
    for(int i=n-1;i>=0;i--)//依次从最后一个结点进行交换
    {
        swap(tree,i,0);
        heapify(tree,0,i);//交换完对第一个结点进行重新构造
    }
}

void build_tree(int tree[],int n)
{
    int lastnode=(n-2)/2;
    for(int i=lastnode;i>=0;i--)
    {
        heapify(tree,i,n);
    }//构造大顶堆要从底向上构造
}

void heapify(int tree[],int i,int n)
{
int parent=i;
int child=2*i+1;
while(child<n)
{
    if(child+1<n&&tree[child+1]>tree[child])//比较左右孩子,选出大的
    {
        child++;
    }
    if(tree[child]>tree[parent])//如果父节点比子节点小就交换
    {
        swap(tree,child,parent);
        parent=child;//改变父节点
    }
    else//反之退出循环,因为当前结点已经是大顶堆结构了
    {
        break;
    }
    child=2*child+1;
}//构造大顶堆


}
int main()
{
    int tree[]={97,15,6,5,3,2,9,8,7,16,4,1,23,9,8,4,2,3,5,65};
    heap_sort(tree,20);
    for(int i=0;i<20;i++)
    printf("%d\t",tree[i]);
    printf("\n");

    return 0;
}

递归版本

#include <stdio.h>
#include <stdlib.h>
void swap(int tree[],int a,int b)
{
    int temp=tree[a];
    tree[a]=tree[b];
    tree[b]=temp;
}//交换函数

void heap_sort(int tree[],int n)
{
    build_tree(tree,n);
    for(int i=n-1;i>=0;i--)//依次从最后一个结点进行交换
    {
        swap(tree,i,0);
        heapify(tree,0,i);//交换完对第一个结点进行重新构造
    }
}

void build_tree(int tree[],int n)
{
    int lastnode=(n-2)/2;
    for(int i=lastnode;i>=0;i--)
    {
        heapify(tree,i,n);
    }//构造大顶堆要从底向上构造
}

void heapify(int tree[],int i,int n)
{
int l=2*i+1;
int r=2*i+2;
int max=i;

if(l<n&&tree[l]>tree[max])
{
    max=l;
}

if(r<n&&tree[r]>tree[max])
{
    max=r;
}
//找左右孩子最大值并记录
if(max!=i)//如果左右孩子比父节点大便进行交换并递归
{
    swap(tree,max,i);
    heapify(tree,max,n);
}

}

int main()
{
    int tree[]={97,15,6,5,3,2,9,8,7,16,4,1,23,9,8,4,2,3,5,65};
    heap_sort(tree,20);
    for(int i=0;i<20;i++)
    printf("%d\t",tree[i]);
    printf("\n");

    return 0;
}

构造小顶堆同理

好好学习天天向上!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值