二叉树的建立(扩展二叉树法)

存储结构

       由于二叉树的特殊性,可以用顺序结构来实现二叉树。如果是完全二叉树,直接按照树的层序依次将每个结点存入数组,相应的下标对应其相同的位置。

       如果是一般的二叉树,尽管层序编号不能反映逻辑关系,但是可以将其按完全二叉树编号,把不存在的结点设置为^ 

       这时候,若情况比较极端:一颗深度为k的右斜树,其只有k个结点,却需要分配2^k -1个存储单元空间,比较浪费。所以一般顺序存储结构只用于完全二叉树。

e.g


顺序结构的普适性不强,考虑链式结构。二叉树每个结点最多有两个孩子,所以二叉链表是比较自然的想法。

lchilddatarchild


结构代码示例

typedef struct Bnode{
	ElemType data;
	struct Bnode *lch,*rch;
}Bnode,*Btree;

e.g



建立



       要建立如上图所示的普通二叉树,自然而然我们需要知道结点的序列。对于二叉树的遍历有前中后三种遍历顺序,而且只有知道一棵树的“前序、中序”或者“中序、后序”才能唯一确定这棵树。

       所以对于一颗普通二叉树,我们对其进行扩展。也就是将二叉树中每个结点的空指针引出一个“虚有的”结点,其值为特定,例如‘#’。一般称这种二叉树为原二叉树的扩展二叉树。对于扩展的二叉树,只要知道一种遍历的序列(前序或后序)即可确定一颗二叉树了。

       图片中前序遍历的序列为AB#D##C##


代码示例(以已知扩展的前序序列为例)

#include<bits/stdc++.h>
using namespace std;

typedef struct Bnode{
	char data;
	Bnode *lch,*rch;
}Bnode,*Btree;

void CreatBtree(Btree &T)
{
	char ch;
	cin>>ch;
	if(ch=='#') T=NULL;
	else{
		T=(Btree)malloc(sizeof(Bnode));
		if(!T) exit(OVERFLOW);
		T->data=ch;
		CreatBtree(T->lch);
		CreatBtree(T->rch);
	}
}

void PreOrderTraverse(Btree T)
{
	if(T==NULL) return ;
	cout<<T->data<<' ';//可改为其他操作 
	PreOrderTraverse(T->lch);
	PreOrderTraverse(T->rch);
}

void InOrderTraverse(Btree T)
{
	if(T==NULL) return ;
	InOrderTraverse(T->lch);
	cout<<T->data<<' ';
	InOrderTraverse(T->rch);
} 

void PostOrderTraverse(Btree T)
{
	if(T==NULL) return ;
	PostOrderTraverse(T->lch);
	PostOrderTraverse(T->rch);
	cout<<T->data<<' ';
}

int main()//以已知扩展前序序列为例 
{
	cout<<"请输入扩展二叉树的扩展前序序列"<<endl;
	Btree root;
	CreatBtree(root);
	cout<<endl;
	cout<<"树的前序为:"<<endl; 
	PreOrderTraverse(root);
	cout<<endl;
	cout<<"树的中序为:"<<endl;
	InOrderTraverse(root);
	cout<<endl;
	cout<<"树的后序为:"<<endl;
	PostOrderTraverse(root);
	cout<<endl;
}


评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值