个人电子笔记,内容多有雷同---(六)1.1_创建二叉树(先序、后序、层序、广义表四种创建方法)
PS:中序创建二叉树是不存在的,因为中序无法确定一棵唯一的二叉树,即可能有两棵或多棵不同的二叉树,它们的中序是一样的
测试二叉树:
1.二叉树的存储结构(链式存储结构)
//二叉树存储
typedef struct BiTNode{
char data;
struct BiTNode *lchild;
struct BiTNode *rchild;
}BiTNode,*BiTree;
2.先序创建二叉树
void PreCreateBiTree(BiTree &T)//先序建立二叉树
{
//根节点->左子树->右子树
ElemType data;
scanf("%c",&data);
if(data=='#')
T=NULL;
else{
T=(BiTree)malloc(sizeof(BiTree));
T->data=data;
PreCreateBiTree(T->lchild);
PreCreateBiTree(T->rchild);
}
}
先序输入:ABD##EF###C##
3.后序创建二叉树
void PostCreateBiTree(BiTree &T,ElemType *Data)//后序建立二叉树
{
//按照根结点->右结点->左节点的顺序就能通过递归构造出一棵二叉树了(反向还原)
ElemType data;
data=Data[cnt-1];
//cout<<cnt<<" "<<data<<endl;
cnt--;
if(data=='#')
T=NULL;
else{
T=(BiTree)malloc(sizeof(BiTree));
T->data=data;
PostCreateBiTree(T->rchild,Data);//先还原右子树
PostCreateBiTree(T->lchild,Data);
}
}
后序创建二叉树时,如果根据 左子树->右子树->根 的顺序递归创建是不可能的,先创建的是子节点无法链接父节点,观察先序输入和后序输入
先序输入:ABD##EF###C##
后序输入:##D##F#EB##CA
后序创建二叉树,无论如何,第一个位置一定是‘#’,只会得到一个空树,但可以发现二者顺序相反,所以我们可以用一个数组来存储后序输入的节点元素,然后通过先序创建的方式从数组末尾往前依次用节点元素来创建二叉树,生成树的字符串的最后一个字符,代表的就是它的根结点,倒数第二个就是它的右孩子,很容易发现,如果我们从字符串后面开始推,按照 根结点 -> 右结点 ->左节点 的顺序就能通过递归构造出一棵二叉树了
4.层次创建二叉树
void LevelCreateBiTree(BiTree &T)
{
BiTree que[505];//队列存储树中元素
int head=0;
int rear=0;
ElemType data;
scanf("%c",&data);
if(data=='#'){
T=NULL;
return;
}
T=(BiTree)malloc(sizeof(BiTree));
T->data=data;
que[rear++]=T;//根节点入队
BiTree p;
while(head!=rear)
{
p=que[head++];//队头出队
scanf("%c",&data);
if(data=='#'){
p->lchild=NULL;
}
else{
p->lchild=(BiTree)malloc(sizeof(BiTree));
p->lchild->data=data;
que[rear++]=p->lchild;//左子树不空则入队
}
scanf("%c",&data);
if(data=='#'){
p->rchild=NULL;
}
else{
p->rchild=(BiTree)malloc(sizeof(BiTree));
p->rchild->data=data;
que[rear++]=p->rchild;//右子树不空则入队
}
}
}
利用其先进先出的性质,把节点的子节点按从左子树->右子树顺序依次创建并入队,一层节点创建完成后,进行出队,创建出队元素的子节点,也是同上原理,创建并入队,就这样队列非空循环,直到队列为空则二叉树创建完成
层次输入:ABCDE####F###
5.先序遍历
void PreOrderTraverse(BiTree T)//先序遍历
{
if(T){
printf("%c ",T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
6.中序遍历
void InOrderTraverse(BiTree T)//中序遍历
{
if(T){
InOrderTraverse(T->lchild);
printf("%c ",T->data);
InOrderTraverse(T->rchild);
}
}
7.后续遍历
void PostOrderTraverse(BiTree T)//后序遍历
{
if(T){
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c ",T->data);
}
}
8.层次遍历
void LevelOrderTraverse(BiTree T)//层次遍历
{
BiTree p;
BiTree que[505];
int head=0;
int rear=0;
que[rear++]=T;
while(head!=rear)
{
p=que[head++];
printf("%c ",p->data);
if(p->lchild!=NULL)
que[rear++]=p->lchild;
if(p->rchild!=NULL)
que[rear++]=p->rchild;
}
}
完整代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
#define ElemType char
int cnt;
//二叉树存储
typedef struct BiTNode{
char data;
struct BiTNode *lchild;
struct BiTNode *rchild;
}BiTNode,*BiTree;
void PreCreateBiTree(BiTree &T)//先序建立二叉树
{
//根节点->左子树->右子树,
//先序输入:ABC##DE#G##F###
ElemType data;
scanf("%c",&data);
if(data=='#')
T=NULL;
else{
T=(BiTree)malloc(sizeof(BiTree));
T->data=data;
PreCreateBiTree(T->lchild);
PreCreateBiTree(T->rchild);
}
}
void PostCreateBiTree(BiTree &T,ElemType *Data)//后序建立二叉树
{
//按照根结点->右结点->左节点的顺序就能通过递归构造出一棵二叉树了(反向还原)
ElemType data;
data=Data[cnt-1];
//cout<<cnt<<" "<<data<<endl;
cnt--;
if(data=='#')
T=NULL;
else{
T=(BiTree)malloc(sizeof(BiTree));
T->data=data;
PostCreateBiTree(T->rchild,Data);//先还原右子树
PostCreateBiTree(T->lchild,Data);
}
}
void LevelCreateBiTree(BiTree &T)
{
BiTree que[505];//队列存储树中元素
int head=0;
int rear=0;
ElemType data;
scanf("%c",&data);
if(data=='#'){
T=NULL;
return;
}
T=(BiTree)malloc(sizeof(BiTree));
T->data=data;
que[rear++]=T;//根节点入队
BiTree p;
while(head!=rear)
{
p=que[head++];//队头出队
scanf("%c",&data);
if(data=='#'){
p->lchild=NULL;
}
else{
p->lchild=(BiTree)malloc(sizeof(BiTree));
p->lchild->data=data;
que[rear++]=p->lchild;//左子树不空则入队
}
scanf("%c",&data);
if(data=='#'){
p->rchild=NULL;
}
else{
p->rchild=(BiTree)malloc(sizeof(BiTree));
p->rchild->data=data;
que[rear++]=p->rchild;//右子树不空则入队
}
}
}
void PreOrderTraverse(BiTree T)//先序遍历
{
if(T){
printf("%c ",T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
void InOrderTraverse(BiTree T)//中序遍历
{
if(T){
InOrderTraverse(T->lchild);
printf("%c ",T->data);
InOrderTraverse(T->rchild);
}
}
void PostOrderTraverse(BiTree T)//后序遍历
{
if(T){
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c ",T->data);
}
}
void LevelOrderTraverse(BiTree T)//层次遍历
{
BiTree p;
BiTree que[505];
int head=0;
int rear=0;
que[rear++]=T;
while(head!=rear)
{
p=que[head++];
printf("%c ",p->data);
if(p->lchild!=NULL)
que[rear++]=p->lchild;
if(p->rchild!=NULL)
que[rear++]=p->rchild;
}
}
int main()
{
BiTree S;
//PreCreateBiTree(S);//先序
ElemType Data[]="##D##F#EB##CA";//层序数组
cnt=strlen(Data);
PostCreateBiTree(S,Data);//后序
//LevelCreateBiTree(S);//层序
printf("先序遍历:");
PreOrderTraverse(S);
puts("");
printf("中序遍历:");
InOrderTraverse(S);
puts("");
printf("后序遍历:");
PostOrderTraverse(S);
puts("");
printf("层序遍历:");
LevelOrderTraverse(S);
puts("");
return 0;
}
运行结果(先序输入)