#include <iostream>
#include <stack>
using namespace std;
#define MAX 100 //字符串最大长度
typedef struct Node //二叉树结点
{
char data;
Node *lchild,*rchild;
} *Btree;
void createBT(Btree &t); //先序构造二叉树
void preorder(Btree &t); //二叉树递归先序遍历
void inorder(Btree &t); //递归中序遍历
void postorder(Btree &t); //递归后序遍历
void preorderbyStack(Btree &t); //先序非递归遍历
void inorderbyStack(Btree &t); //中序非递归遍历
void postorderbyStack(Btree &t);//后序非递归遍历
/*****************最近公共父结点算法LCF*******************/
int findNode1(Btree &t,char ch,char p[]); //找出结点1到根的路径
int findNode2(Btree &t,char ch,char q[]); //找出结点2到根的路径
void compare(char *p,char *q); //比较两条路径,找到第一个公共结点
static int i = 0;
static int j = 0;
/*****************最近公共父结点算法LCF*******************/
void createBT(Btree &t) //先序创建二叉树 #表示空指针
{
char ch;
cin>>ch;
if(ch == '#') t = NULL;
else
{
if(!(t = new Node)) exit(1);
t ->data = ch; //递归创建二叉树
createBT(t->lchild);
createBT(t->rchild);
}
}
void preorder(Btree &t)
{
if(t == NULL)
return ;
else
{
cout<<t->data<<" ";
preorder(t->lchild);
preorder(t->rchild);
}
}
void inorder(Btree &t)
{
if(!t)
return;
else
{
inorder(t->lchild);
cout<<t->data<<" ";
inorder(t->rchild);
}
}
void postorder(Btree &t)
{
if(!t)
return;
else
{
postorder(t->lchild);
postorder(t->rchild);
cout<<t->data<<" ";
}
}
void preorderbyStack(Btree &t)
{
stack<Node*>s;
Node *p = t;
while (p || !s.empty())
{
if(p)
{
cout<<p->data<<" "; //先序遍历二叉树,先访问根节点,再访问左子树
s.push(p);
p = p->lchild;
}
else
{
p = s.top();
s.pop();
p = p->rchild;
}
}
}
void inorderbyStack(Btree &t)
{
stack<Node*>s;
Node *p = t;
while (p || !s.empty())
{
if(p)
{
s.push(p);
p = p->lchild;
}
else
{
p = s.top();
cout<<p->data<<" "; //中序遍历二叉树,先访问左子树
s.pop();
p = p->rchild;
}
}
}
void postorderbyStack(Btree &t)
{
stack<Node*> s;
Node *p = t;
Node *flag = nullptr;
while (p || !s.empty())
{
if(p) //后序遍历先访问左结点,再右结点,最后根结点
{
s.push(p);
p = p->lchild;
}
else
{
p = s.top();
if( p->rchild&&p->rchild != flag) //如果右子树不为空且没有被访问过
{
p = p->rchild; //转到右子树
s.push(p);
p = p->lchild;
}
else //如果右子树为空,当前结点为访问结点
{
s.pop();
cout<<p->data<<" ";
flag = p; //把刚刚访问的结点做标记,防止重复访问
p = nullptr; //把p置为空指针,如果不置位空。还要压入栈一次,就造成死循环
}
}
}
}
bool isEmpty(Btree &t)
{
return t == NULL?true:false;
}
int findNode1(Btree &t,char ch,char p[])
{
if(!t)
return 0;
else if(t->data == ch) //从所给的结点出发,搜索到达根节点的路径,并将路径记录下来
{
*(p+i) = t->data;
++i;
return 1;
}
else
{
if(findNode1(t->lchild, ch, p))
{
*(p+i) = t->data;
++i;
return 1;
}
else if(findNode1(t->rchild, ch, p))
{
*(p+i) = t->data;
++i;
return 1;
}
else
return 0;
}
}
int findNode2(Btree &t,char ch,char q[])
{
if(!t)
return 0;
else if(t->data == ch)
{
*(q+j) = t->data;
++j;
return 1;
}
else
{
if(findNode2(t->lchild, ch, q))
{
*(q+j) = t->data;
++j;
return 1;
}
else if(findNode2(t->rchild, ch, q))
{
*(q+j) = t->data;
++j;
return 1;
}
else
return 0;
}
}
void compare(char *p,char *q) //比较两条路径,第一个不同的路径点的父结点就是其公共父结点
{
i--;
j--;
while(p[i] == q[j])
{
i--;
j--;
}
cout<<"LCF is :"<<p[i+1]<<endl;
}
int main()
{
//测试用例:abc##de#g##f###
Btree t = new Node;
createBT(t);
preorder(t);
cout<<endl;
preorderbyStack(t);
cout<<endl;
inorder(t);
cout<<endl;
inorderbyStack(t);
cout<<endl;
postorder(t);
cout<<endl;
postorderbyStack(t);
cout<<endl;
char a[MAX];
char b[MAX];
findNode1(t, 'c',a);
findNode2(t, 'e',b);
compare(a, b);
return 0;
}
前序构造二叉树 字符#表示空。
二叉树的递归遍历与非递归遍历。后者借助栈
最近公共父节点是指对于二叉树中的两个结点 找到最近的公共父节点
posted on
浙公网安备 33010602011771号