微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

数据结构-二叉树的存储结构

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 举报,一经查实,本站将立刻删除。

相关推荐