树与二叉树章节总结

导图

在这里插入图片描述

笔记

树的一些术语

(1)结点的度和树的度:树中某个结点的子树的个数称为该结点的度。树中所有结点的度中的最大值称为树的度。

(2)分支结点与叶子结点:树中度不为零的结点称为分支结点,度为零的结点称为叶子结点。

(3)树的高度:树的高度又称为树的深度,其为结点的最大层次。

(4)森林:n个互不相交的树的集合。

二叉树的遍历:

在这里插入图片描述

先序遍历:

(1)访问根结点 (2)先序遍历左子树 (3)先序遍历右子树

如上图的遍历结果为5,3,1,4,7,6,8

中序遍历:

(1)中序遍历左子树 (2)访问根结点 (3)中序遍历右子树

如上图的遍历结果为1,3,4,5,6,7,8

后序遍历:

(1)后序遍历左子树 (2)后序遍历右子树 (3)访问根结点

如上图的遍历结果为1,4,3,6,8,7,5

线索二叉树:遍历一颗二叉树的结果是一个结点的线性序列,可以利用这些空链域存放指向结点的前区结点和后继结点的地址。其规定是当某结点的左指针为空时,令该指针指向这个线性序列中该结点的前驱结点;当某结点的右指针为空时,令该指针指向这个线性序列中该结点的后继结点,这样的指向该线性序列中的“前驱结点”和“后继结点”的指针称为线索。为了在线索二叉树中区分左指针指向的是左孩子还是前驱结点,右指针指向的是右孩子还是后驱结点,在结点的储存结构上增加两个标志位来区分。左标志ltag={0,1}(0表示左孩子指向左孩子结点,1表示右孩子指向前驱结点),右标志rtag={0,1}(0表示右孩子指向右孩子结点,1表示右孩子指向后继结点)。创建线索二叉树的算法中为了方便,设置一个头结点。

在这里插入图片描述

哈夫曼树:在n个带权叶子结点构成的所有二叉树中,带权路径长(WPL)最小的的二叉树称为哈夫曼树也称最优二叉树。

哈希冲突:在构建哈希表时可能存在两个关键字k1和k2有k1!=k2,但会出现k1的存储地址和k2的存储地址相同的情况。

避免哈希冲突:装填因子越小冲突的可能性就越小反之冲突的可能性就越大,装填因子=已存入的元素数除以哈希因子地址空间的大小。为了避免哈希冲突有线性探测法、平方探测法和拉链法。线性探测法是从发生冲突的地址开始,依次探测冲突地址往后的地址,线性探测法易发生堆集。平方探测法即从发生冲突的地址(设为d)开始,以d+1平方,d+2平方,d+3平方以此类推。较不容易发生堆集。拉链法是把所有的同义词(存储地址冲突的两个或多个储存元素)用单链表链接起来。

疑难

拉链法能够高效的解决哈希冲突,但是始终无法理解拉链法是如何具体解决哈希冲突的,借课本中的拉链法构建哈希表以及查找的算法加深理解。

拉链法构造哈希表

类型;

typedef int KeyType;
typedef struct node
{
    KeyType key;//储存关键字地址
    struct node *next;//结点指针
}NodeType;//单链表结点类型
typedef struct
{
    NodeType * firstp;//首结点指针
}HashTable;

代码;

void InsertHT(HashTable ha[],int &n,int p,KeyTyoe k)
{
    int adr;
    adr=k%p;//哈希公式计算哈希值,其中k是要准备储存的元素
    NodeType *q;
    q=(NodeType *)malloc(sizeof(NodeType));//开辟储存空间
    q->key=k;//元素k储存在q结点中
    q->next==NULL;//构建链表结点
    if(ha[adr].firstp==NULL)//adr是目标元素储存的地址,在这是判断在改地址下是否已经有储存元素
        ha[adr].firstp=q;//若无,则直接储存
    else//若有则用头插法接入该地址,构建一条链表
    {
        q->next=ha[adr].firstp;
        ha[adr].firstp=q;
    }
    n++;//哈希表结点数加1,n主要是储存哈希表长度用于后序查找操作
}
void CreateHT(HashTable ha[],int &n,int m,int p,KeyType keys[],int n1)//创建哈希表
{
    for(int i=0;i<m;i++)
        ha[i].firstp=NULL;
    n=0;
    for(i=0;i<n1;i++)
        InsertHT(ha,n,p,keys[i]);
}

查找操作

void SearchHT(Hashtable ha [],int p,KeyType k)//哈希表中查找关键字
{
    int i=0,adr;
    adr=k%p;
    NodeType *q;
    q=ha[adr].firstp;
    while(q!=NULL)
    {
        i++;
        if(q->key==k)
            break;
        q=q->next;
    }
    if(q!=NULL)
        printf("成功:关键字%d比较%d次\n“,k,i);
    else
        printf("失败:关键字%d比较%d次\n",k,i);
}

;
}
if(q!=NULL)
printf("成功:关键字%d比较%d次\n“,k,i);
else
printf(“失败:关键字%d比较%d次\n”,k,i);
}


总结:实现拉链法构造和查找简单来说先定义一个数组a[n]用于储存哈希数值,通过哈希公式计算出哈希值p后将目标元素链表化存储在a[p]中,也就是说每一个数组单元都存储一条链表,如果哈希值相同则将同义词入与之哈希值对应的链表的后面,查找是先找到储存目标链表的数组单元,接着遍历该链表即可完成查找。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值