数据结构概述3 对称矩阵、树和二叉树

目录

对称矩阵

定义

定义

基本术语

二叉树

二叉树的五中基本形态

两类特殊的二叉树

满二叉树

 完全二叉树

 二叉树的存储结构

顺序存储

二叉链表存储

三叉链表存储

二叉树的基本操作

1.建立一棵空二叉树

2.生成一棵二叉树

3.二叉树中插入一个左子树结点

4.二叉树中插入一个右子树结点

5.删除结点parent的左子树

6.删除结点parent的右子树

二叉树的遍历

DLR(根左右 称为先序遍历)

LDR(左根右 称为中序遍历)

LRD(左右根 称为后序遍历)

线索二叉树

先序线索二叉树

 中序线索二叉树

 后序线索二叉树

树和森林的存储

双亲存储法

 孩子链表存储法

 双亲孩子存储法

 左孩子右兄弟存储法

二叉树、树和森林的转换

森林转换为二叉树(使用左孩子右兄弟的方法)

 二叉树转换为树和森林

最优二叉树(哈夫曼树)

定义

哈夫曼树的建立过程

 哈夫曼编码


对称矩阵

定义

1.对称矩阵中的元素关于主对角线对称,aij=aji,元素个数n^2

2.压缩存储,元素个数n(n+1)/2

//以下C语言函数的功能是将一维数组a中压缩存储的下三角4×4阶对称矩阵按矩阵格式输出。
print(int a[])
{ 
    int i,j;
    for(i=0;i<4;i++)
    { 
        for(j=0;j<4;j++)
        {
            if(i>=j) 
                printf("%4d",a[i*(i+1)/2+j]);
            else 
                printf("%4d",a[j*(j+1)/2+i]);
        }
        printf("\n");
    }
}

定义

1.树(Tree)是n(n≥0)个有限数据元素的集合

2.n=0时,树为空树

3.树的根结点没有前驱结点,除根结点之外的所有结有且只有一个前驱结点

基本术语

1.结点:表示树中的元素

2.结点的度:结点子树的个数(该结点的子结点个数)

3.叶结点:度为0的结点(没有子结点)

4.分枝结点:度不为0的结点

5.树的度:各结点度的最大值

6.子结点(孩子结点)

7.父结点(双亲结点)

8.兄弟结点

9.结点的祖先:从根到该结点所经分支上的所有结点

10.子孙:以某结点为根的子树中的任一结点都称为该结点的子孙

11.结点的层数:从该结点到树的根结点的层数

12.堂兄弟结点:父结点在同一层且双亲结点不相同的结点互为堂兄弟结点

13.树的度(高度或深度):树中所有结点的最大层数称为树的度

14.路径、路径长度:结点的层数-1

15.有序树和无序树

16.森林:任何一棵树,删去根结点就变成了森林

二叉树

二叉树的五中基本形态

两类特殊的二叉树

满二叉树

结点个数:2^k-1

 

 完全二叉树

 

 二叉树的存储结构

顺序存储

二叉链表存储

三叉链表存储

 

二叉树的基本操作

1.建立一棵空二叉树

//初始化建立二叉树bt的头结点,0表示建立失败,1表示成功
int Initiate (BiTree bt)
{ 
    if((bt=(BiTNode *)malloc(sizeof(BiTNode)))==NULL) 
        return 0;
    bt->lchild=NULL;
    bt->rchild=NULL;
    return 1;
}

2.生成一棵二叉树

//生成一棵以x为根结点的数据域信息的二叉树
BiTree Create(elemtype x)
{ 
    BiTree p;
    if ((p=(BiTNode *)malloc(sizeof(BiTNode)))==NULL) 
        return NULL;
    p->data=x;
    p->lchild=NULL;
    p->rchild=NULL;
    return p;
}

3.二叉树中插入一个左子树结点

//在二叉树bt的结点parent的左子树中插入结点数据元素x
BiTree InsertL(BiTree bt,elemtype x,BiTree parent)
{ 
    BiTree p;
    if (parent==NULL) 
    { 
        printf(“\n插入出错”);
        return NULL;
    }
    if ((p=(BiTNode *)malloc(sizeof(BiTNode)))==NULL) 
        return NULL;
    p->data=x;
    p->lchild=NULL;
    p->rchild=NULL;
    if (parent->lchild==NULL)
        parent->lchild=p;
    else 
    { 
        p->lchild=parent->lchild;
        parent->lchild=p; 
    }
    return bt;
}

4.二叉树中插入一个右子树结点

//在二叉树bt的结点parent的右子树中插入结点数据元素x
BiTree InsertR(BiTree bt,elemtype x,BiTree parent)
{ 
    BiTree p;
    if (parent==NULL) 
    { 
        printf(“\n插入出错”);
        return NULL;
    }
    if ((p=(BiTNode *)malloc(sizeof(BiTNode)))==NULL) 
        return NULL;
    p->data=x;
    p->lchild=NULL;
    p->rchild=NULL;
    if (parent->rchild==NULL)
        parent->rchild=p;
    else 
    { 
        p->rchild=parent->rchild;
        parent->rchild=p; 
    }
    return bt;
}

5.删除结点parent的左子树

//在二叉树bt中删除结点parent的左子树
BiTree DeleteL(BiTree bt,BiTree parent)
{ 
    BiTree p;
    if (parent==NULL||parent->lchild==NULL)
    { 
        printf("\n删除出错");
        return NULL;
    }
    p=parent->lchild;
    parent->lchild=NULL;
    free(p);//当p为非叶结点时,这样删除仅释放了所删子树根结点的空间
    return br;//若要删除子树分支中的结点,需用后面介绍的遍历操作来实现
}

6.删除结点parent的右子树

//在二叉树bt中删除结点parent的右子树
BiTree DeleteL(BiTree bt,BiTree parent)
{ 
    BiTree p;
    if (parent==NULL||parent->rchild==NULL)
    { 
        printf("\n删除出错");
        return NULL;
    }
    p=parent->rchild;
    parent->rchild=NULL;
    free(p);//当p为非叶结点时,这样删除仅释放了所删子树根结点的空间
    return br;//若要删除子树分支中的结点,需用后面介绍的遍历操作来实现
}

二叉树的遍历

DLR(根左右 称为先序遍历)

int PreOrder(BiTree bt)
{ 
    if (bt==NULL) //递归调用结束条件
        return0; 
    Visit(bt->data);//访问结点的数据域
    PreOrder(bt->lchild);//先序递归遍历bt左子树
    PreOrder(bt->rchild);//先序递归遍历bt右子树
    return 1;
}

LDR(左根右 称为中序遍历)

int MidOrder(BiTree bt)
{ 
    if (bt==NULL) //递归调用结束条件
        return0; 
    MidOrder(bt->lchild);//中序递归遍历bt左子树
    Visit(bt->data);//访问结点的数据域
    MidOrder(bt->rchild);//中序递归遍历bt右子树
    return 1;
}

LRD(左右根 称为后序遍历)

int PostOrder(BiTree bt)
{ 
    if (bt==NULL) //递归调用结束条件
        return0; 
    PostOrder(bt->lchild);//后序递归遍历bt左子树
    PostOrder(bt->rchild);//后序递归遍历bt右子树
    Visit(bt->data);//访问结点的数据域
    return 1;
}

线索二叉树

1.当结点有左子树,即lchild域不为空时,LTag为0

2.当结点没有左子树,即lchild为空时,令lchild域指向该结点的前驱,LTag为1

3.当结点有右子树,即rchild域不为空时,RTag为0

3.当结点没有右子树,即rchild为空时,令rchild域指向该结点的后继,RTag为1 

先序线索二叉树

abdce

 

 中序线索二叉树

bdaec

 后序线索二叉树

dbeca

树和森林的存储

双亲存储法

 孩子链表存储法

 双亲孩子存储法

 左孩子右兄弟存储法

二叉树、树和森林的转换

森林转换为二叉树(使用左孩子右兄弟的方法)

 二叉树转换为树和森林

最优二叉树(哈夫曼树)

定义

1.指对于一组带有确定权值的叶结点,构造的具有最小带权路径长度的二叉树

2.结点的路径长度:从根结点到该结点的路径上分支的数目

3.结点权值:附加在结点上的信息

4.结点带权路径:结点上权值与该结点到根之间的路径长度的乘积

5.二叉树的路径长度:指由根结点到所有叶结点的路径长度之和

6.二叉树的带权路径长度:WPL(T) =Σwklk (权重为wk,路径为lk)

 WPL(T)=1×2 +8×2 +5×3+7×4+2×2=65

哈夫曼树的建立过程

每次选两个最小的权构造哈夫曼树

 哈夫曼编码

左分支代表0,右分支代表1

{5,2,10,6,7}   每次选两个最小的权构造哈夫曼树

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yao2424022071

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值