数据结构(第五章)

折月煮酒 提交于 2020-02-21 05:18:42

树下
第一讲
一.堆
什么是堆?
在讲堆之前,我们先看看什么是优先队列。
优先队列:是一种特殊的队列,从名称上看,优先,顾名思义,取出的元素是按照一定的优先级出队的,而不是元素进入队列的先后顺序。
优先队列的完全二叉树表示
堆的两个特性:
结构性:用数组表示的完全二叉树。
有序性:任一结点的关键字是其子树所有结点的最大值(或最小值)。
由最大值和最小值我们可以引出一个新概念“最大堆”“最小堆”
最大堆:每个结点的元素值不小于其子结点的元素值。
最小堆:每个结点的元素值不大于其子结点的元素值。
主要在最大堆的操作上面,因为最大堆会了,最小堆自然就不成问题了
最大堆的创建

typedef struct HeapStruct *MaxHeap;
struct HeapStruct
{
    ElementType *Elements[];//存储堆元素
    int Size;//堆元素个数
    int Capacity;//堆的最大容量
}
MaxHeap Create(int MaxSize)
{
    MaxHeap H=malloc(sizeof(struct Heapstruct));
    H->Elements=malloc((MaxSize+1)*sizeof(sizeof(ElementType));
    H->Size=0;
    H->Capacity=MaxSize;
    H->Elements[0]=Maxdata;//把Maxdata变成mindata也同样使用于创建最小堆
    return 

最大堆的插入
我们的算法就是,将新增的结点插入到从其父结点到根结点的有序序列中,我们就能保证最大堆的有序性并完成插入。

void Insert(MaxHeap H,ElementType item)
{
    int i;
    if(IsFull(H))
    {
        printf("堆满");
        return;
    }
    i=++H->Size;//i指向插入堆中的最后一个元素的位置
    for(;H->Elements[i/2]<item;i/=2)
    {
        H->Elements[i]=H->Elements[i/2];//向下过滤结点
    }
    H->Elements[i]=item;//进行插入
}

最大堆的删除
我们最大堆的删除操作的算法就是,取出根结点,也就是我们最大的元素,同时删除堆的一个结点

ElementType DeleteMax(MaxHeap H)
{
    int Parent,Child;
    ElementType MaxItem,temp;
    if(IsEmpty)//堆满
    {
        printf("堆满");
        return;
    }
    MaxItem=H->Elements[1];//取出最大值,根结点
    temp=H->Elements[H->Size--];
    for(Parent=1;Parent*2<=H->Size;Parent=Child)//用最大堆的最后一个元素从根结点开始向上过滤下层结点
    {
        Child=Parent*2;
        if((Child!=H->Size)&&(H->Elements[Child]<H->Elements[Child+2]))
        {
            Child++;//指向较大的一方
        }
        if(temp>=H->Elements[Child])
            break;
       else
           H->Elements[Parent]=H->Elements[Child];     
    }
    H->Elements[Parent]=temp;
    return MaxItem;
}

第二讲
一.赫夫曼树的定义及原理
赫夫曼大叔说,从树的一个结点到另一个结点之间的分支构成两个结点之间的路径,路径上的分支数目称作路径长度,然而树的路径长度等于从根结点到树的每一个结点的路径长度之和,带权路径最小的二叉树被称为赫夫曼树,也称为最优二叉树。
赫夫曼算法(用来查找赫夫曼树)描述:
根据给定的n个权值{w1,w2…}构成的n棵二叉树的集合F={T1,T2…},其中每棵二叉树Ti中只有一个带权为wi根结点,其左右子树均为空。在F中选取两棵根结点的权值最小的树作为左右子树,然后构造一个新的二叉树,并且新的二叉树的根结点的权值为其左右树上根结点的权值之和;在F中删除这两棵树,同时将新得到的二叉树加入F中,重复上述步骤,直到F只含一棵树为止。然后这棵树就是赫夫曼树。说了那么多,其实我也不怎么懂…
心得:通过这章结的学习,树,和森林看似复杂,但是我们可以通过二叉树之类的有一定规律的树来规范它,一旦有了规律,我们顺着规律走,就柳暗花明了,其次,以前喜欢用数组,是因为其简单易操作,但是现在发现,它太浪费空间了,而树的结构节省了很多空间,提高了效率。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!