1、顺序存储
二叉树的顺序存储采用的存储结构是顺序表(数组)。但是只有完全二叉树才可以使用顺序表存储。如果想要存储普通二叉树,我们就要先将普通二叉树转换为完全二叉树。
普通二叉树转完全二叉树的方法很简单,只需给二叉树额外添加一些节点,将其"拼凑"成完全二叉树即可。
上图中,左侧是普通二叉树,右侧是转化后的完全(满)二叉树。
解决了二叉树的转化问题,接下来学习如何顺序存储完全(满)二叉树。
完全二叉树的顺序存储,仅需从根节点开始,按照层次依次将树中节点存储到数组即可。
完全二叉树在数组的存储状态:
存储由普通二叉树转化来的完全二叉树也是如此:
从顺序表中还原完全二叉树也很简单。我们知道,完全二叉树具有这样的性质,将树中节点按照层次并从左到右依次标号(1,2,3,...),若节点 i 有左右孩子,则其左孩子节点为 2*i,右孩子节点为 2*i+1。此性质可用于还原数组中存储的完全二叉树。
2、链式存储
因为并不是每个二叉树都是完全二叉树,所以普通二叉树在转换成完全二叉树时,会徒增很多空结点,这些空结点还都需要存储在数组中,这无疑对内存空间造成了大量的浪费。
所以。树的存储我们经常采用的是链式存储结构。
普通二叉树(左) 二叉树的链式存储结构(右)
采用链式存储二叉树时,其节点结构由 3 部分构成:
- 指向左孩子节点的指针(Lchild);
- 节点存储的数据(data);
- 指向右孩子节点的指针(Rchild);
如图:
表示结点结构的C语言代码:
typedef struct BiTNode{
TElemType data;//数据域
struct BiTNode *lchild,*rchild;//左右孩子指针
struct BiNode *parent;//父结点指针
}BiTNode,*BiTree;
通常情况下也可不写父结点指针,这是为了我们方便找到结点的父结点而写的。
这样的链表结构,通常称为三叉链表。
完整的二叉链表存储代码:
#include<stdio.h>
#include<stdlib.h>
#define TElemType int
typedef struct BiTNode{
TElemType data;//数据域
struct BiTNode *lchild,*rchild;//左右孩子指针
struct BiNode *parent;//父结点指针
}BiTNode,*BiTree;
void CreateBiTree(BiTree *T){
*T=(BiTNode*)malloc(sizeof(BiTNode));//生成一个根结点
(*T)->data=1;
(*T)->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->data=2;
(*T)->rchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->rchild->data=3;
(*T)->lchild->lchild=(BiTNode*)malloc(sizeof(BiTNode));
(*T)->lchild->lchild->data=4;
(*T)->lchild->rchild=NULL;
(*T)->lchild->lchild->lchild=NULL;
(*T)->lchild->lchild->rchild=NULL;
}
int main(){
BiTree Tree;//申请一个根结点结构体地址空间
CreateBiTree(&Tree);
printf("%d",Tree->lchild->lchild->data);
return 0;
}
输出:
原文地址:https://www.jb51.cc/wenti/3286293.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。