您的位置:首页 > 其它

二叉链表(链式二叉树)的非递归创建

2016-05-15 10:50 211 查看
这里我采用的是先序非递归创建二叉树。思路很简单:

首先要有一个结点数组。

1.取第一个结点,是否为空,不是就作为树根,压栈,是空则树根为空,结束。

2.取下一个结点a。

3.取栈顶结点b,如果栈顶结点没有左孩子,那么b->lchild=a,如果栈顶结点b有左孩子没有右孩子,那么 b->rchild=a,如果栈顶结点左孩子右孩子都存在,那么弹栈,重复3。

4.重复2-4,直到栈空,或者所有结点都被加入树中。

那么问题来了,怎么判断栈顶结点是否存在左孩子和右孩子呢。比较简单的想法就是增设一个标志位,借助标志位来判断。不过在写树的时候,显然还是希望每个结点不要多出来一些奇怪的变量,只在建树的时候有用,其它地方都没有用处。那么是否可以通过左右孩子指针域的值来判断呢,答案是肯定的。我们可以在创建每个结点的时候将这些左右孩子指针回指自身,以此来代表这些结点的左右孩子是否存在,操作易于实现,判断起来也很方便。

下贴代码:

我这里假设每个结点都用一个字符来代表,’#’就代表这个结点为空。然后这一串字符就构成了串 nodes,作为函数的输入。当然可以改变这种方式,读者只需稍作修改。

#include <iostream>
#include <string>
#include <stack>
using namespace std;

typedef struct BiTreeNode{
char ch;
BiTreeNode *lchild;
BiTreeNode *rchild;
}BiTreeNode,*BiTree;

BiTreeNode* CreateTree(string nodes){//构造二叉链表的函数
//先序非递归法构造链式二叉树
stack<BiTreeNode*> stack1;
BiTreeNode *pd1,*pd2;//指向二叉树结点的指针
bool flag;
int n=nodes.size();
BiTreeNode *root=NULL;
if(nodes[0]!='#'){//不是空树
pd1=new BiTreeNode;
pd1->lchild=pd1;//左孩子指针回指
pd1->rchild=pd1;//右孩子指针回指
pd1->ch=nodes[0];
root=pd1;
int k=0;
stack1.push(pd1);//树根入栈
while(!stack1.empty()&&k!=n-1){
flag=false;
if(nodes[++k]!='#'){
pd2=new BiTreeNode;
pd2->ch=nodes[k];
pd2->lchild=pd2;//左孩子指针回指
pd2->rchild=pd2;//右孩子指针回指
flag=true;
}else
pd2=NULL;
pd1=stack1.top();
while(pd1->lchild!=pd1&&pd1->rchild!=pd1){//找到没有左右孩子的栈顶结点
stack1.pop();
pd1=stack1.top();
}
if(pd1->lchild==pd1)//没有左孩子
pd1->lchild=pd2;
else
pd1->rchild=pd2;
if(flag)//pd2不是空指针
stack1.push(pd2);//pd2入栈
}
}
return root;
}

void preordertraverse(BiTree T){//先序遍历
if(T){
cout << T->ch;
preordertraverse(T->lchild);
preordertraverse(T->rchild);
}
}

void inordertraverse(BiTree T){//中序遍历
if(T){
inordertraverse(T->lchild);
cout << T->ch;
inordertraverse(T->rchild);
}
}

int main(){
string nodes;
cin >> nodes;
BiTree T=CreateTree(nodes);
preordertraverse(T);//先序遍历
cout << endl;
inordertraverse(T);//中序遍历
cout << endl;
return 0;
}


附一张运行结果图:

输入:AB#DF###C#E##

输出:



原本我打算将树写成一个模板类,在写构造函数时发现,虽然递归创建树很简洁,但是写在构造函数里很不方便,于是自己在纸上画图,想出了这个算法。其中恐有讹误,如果发现请联系作者指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二叉树