菜鸟学习数据结构之用堆排序理解二叉树

来源:互联网 发布:linux rpm下载 编辑:程序博客网 时间:2024/06/05 07:04

简介

感谢啊哈算法提供的代码和思路,这里是对知识和代码的个人理解并无其他。
关于二叉树有几个结论给老子记下来:

  • 树,就是没有回路的图。二叉树,就是每个节点 最多 有两个儿子;如果每个节点都有两个儿子的二叉树,就是满二叉树;而完全二叉树的一个重要特点就是如果有右儿子,那么就肯定有左儿子,反过来是不成立的。

好,用堆排序的算法来巩固一下,你要关注的就是关于如何建堆、建最小堆。

#include <stdio.h>    //关于建堆和堆排序    int h[101];    int n;//堆中的数    /*     *交换堆中的两个元素     */    void swap(int x,int y){        int t;        t = h[x];        h[x] = h[y];        h[y] = t;    }    //向下调整函数,其中i为结点编号    void siftdown(int i){        int t;//存储结点编号        int flag = 0;//是否有向下调整的需要,有为0,没有为1;        //此处,完全二叉树至少是有左儿子的        while(i*2<=n&&flag==0){            //判断跟左儿子的大小关系,用t存放值较小的编号            if(h[i]<h[i*2]){                t = i;            }else{                t = i*2;            }            //如果有右儿子,再比较跟右儿子的大小            if(i*2+1<=n){                if(h[t]>h[i*2+1]){                    t = i*2+1;                }            }            //如果发现最小的值已经不是自己,则需要交换了            if(t!=i){                swap(t,i);//进行交换                i = t;//为了下一步的调整            }else{                flag = 1;//不需要调整了            }        }    }    //关于建最小堆:就是完全二叉树从最后一个非叶节点(n/2)的向上调整    void creat(){        int i;        for(i=n/2;i>=1;i--){            siftdown(i);        }    }    //删除顶部的数    int deletemax(){        int t;        t = h[1];//这个就是堆顶的值,也是我们要删除的值,下面的代码是继续建最小堆        h[1] = h[n];//将最后一个数放到堆顶,因为原堆顶我们要删除了        n--;//自然而然,堆元素的个数递减        siftdown(1);//向下调整建立最小堆,从顶点开始调整,所以传入1        return t;//说好的要删掉它的    }    //万事俱备,就欠主函数    int main(){        int i,num;//num为要堆排序的元素个数        printf("请输入要排序元素的个数:");        scanf("%d",&num);        printf("请输入要排序的数:");        for(i=1;i<=num;i++){            scanf("%d",&h[i]);        }        n = num;//因为我们前面的函数有用到n:堆中的元素个数        //建立最小堆,因为是从小到大排序        creat();        //删除顶部元素,需要删除n次        for(i=1;i<=num;i++){            printf("%d",deletemax());//这样就把删除的数收入囊中了        }        return 0;    }
0 0