主题:[讨论]标准C++二叉树三叉链表递归改非递归算法
这个递归算法 改成非递归的,有高手会么?
#include <iostream>
#include <string>
#include <queue>
using namespace std;
class BiNode{ //节点的定义
public:
char data; //用一个整数表示节点的值
BiNode *lchild; //节点的左孩子指针
BiNode *rchild; //节点的右孩子指针
BiNode *parent; //父节点指针
};
class BiTree{ //二叉树的定义
private:
void ClearAt(BiNode *node); //清除子树递归函数
int NodeAt(BiNode *node); //获取子树节点数递归函数
void PostOrderAt(BiNode *node); //后续遍历递归函数
void InOrderAt(BiNode *node); //中序遍历递归函数
void PreOrderAt(BiNode *node); //前序遍历递归函数
int DepthAt(BiNode *node); //求子树的深度
BiNode *root; //二叉树的根节点
string strTable; //保存用于创建二叉树的广义表字符串
public:
void Init(); //初始化为一颗空二叉树
void Create(string str); //由广义表形式串s创建二叉树
void Out(); //按广义表形式输出到控制台
int Depth(); //求二叉树的深度
int Node(); //求节点数
int Leaf(); //求叶子数
void PreOrder(); //前序遍历
void InOrder(); //中序遍历
void PostOrder(); //后序遍历
void LeOrder(); //层序遍历
void Copy(BiTree &biTree); //复制二叉树到biTree
void Clear(); //清空
bool Find(char data); //查找
};
void BiTree::Init(){ //初始化为一颗空二叉树
root = NULL;
}
void BiTree::Create(string str){ //由广义表形式串s创建二叉树
Init(); //初始化二叉树,使根节点为空
strTable = str; //保存这个字符串
char ch; //当前节点的值
int k; //用k作为处理结点的左子树和右子树的标记,k=1处理左子树,k=2处理右子树
BiNode* s[50]; //s数组作为存储二叉树中根结点指针的栈
int top = -1; //top作为s栈的栈顶指针
BiNode *p; //定义p为指向二叉树结点的指针
BiNode *parent = NULL; //指向当前节点的父节点
int count = 0;
ch = str.at(count);
while (count < str.length()){ //每循环一次处理一个读入的字符,直到扫描到'@'字符为止
switch(ch){
case '(':
top++;
s[top] = p;
k = 1;
parent = p; //如果遇到'(',说明上一个节点是后面节点的父节点。用parent保存上一个节点。
break;
case ')':
top--;
break;
case ',':
k = 2;
break;
case ' ':
break;
default:
p = new BiNode;
p->data = ch;
p->parent = parent;
p->lchild = p->rchild = NULL;
if(root == NULL) root=p;
else{
if(k == 1)
s[top]->lchild = p;
else
s[top]->rchild = p;
}
}
count++;
if (count < str.length())
ch = str.at(count);
}
}
void BiTree::Out(){ //按广义表形式输出到控制台
cout<<strTable<<endl;
}
int BiTree::Depth(){ //求二叉树的深度
return DepthAt(root);
}
int BiTree::Node(){ //求节点数
return NodeAt(root);
}
int BiTree::Leaf(){ //求叶子数
queue <BiNode*> nodeQueue; //使用c++标准模板queue,表示一个节点队列
BiNode *p;
int count = 0; //叶子计数
nodeQueue.push(root); //根节点进入队列
p = root;
while (!nodeQueue.empty()){
if (p->lchild != NULL)
nodeQueue.push(p->lchild); //左孩子进入队列
if (p->rchild != NULL)
nodeQueue.push(p->rchild); //右孩子进入队列
if ((p->lchild == NULL) && (p->rchild == NULL)) //判断根是否是叶子节点
count++;
nodeQueue.pop(); //根节点出队列
if (!nodeQueue.empty())
p = nodeQueue.front(); //p重新指向队列第一个元素
}
return count;
}
void BiTree::PreOrder(){ //前序遍历
PreOrderAt(root);
}
void BiTree::InOrder(){ //中序遍历
InOrderAt(root);
}
void BiTree::PostOrder(){ //后序遍历
PostOrderAt(root);
}
void BiTree::LeOrder(){ //层序遍历(用队列实现)
queue <BiNode*> nodeQueue; //使用c++标准模板queue,表示一个节点队列
BiNode *p;
nodeQueue.push(root); //根节点进入队列
p = root;
while (!nodeQueue.empty()){
if (p->lchild != NULL)
nodeQueue.push(p->lchild); //左孩子进入队列
if (p->rchild != NULL)
nodeQueue.push(p->rchild); //右孩子进入队列
cout<<nodeQueue.front()->data<<' '; //输出根节点
nodeQueue.pop(); //根节点出队列
if (!nodeQueue.empty())
p = nodeQueue.front(); //p重新指向队列第一个元素
}
}
void BiTree::Copy(BiTree &biTree){ //复制二叉树到biTree,用本二叉树的广义表字符串构造biTree
biTree.Create(strTable);
}
void BiTree::Clear(){ //清空
ClearAt(root);
}
bool BiTree::Find(char data){ //查找
queue <BiNode*> nodeQueue; //使用c++标准模板queue,表示一个节点队列
BiNode *p;
int count = 0; //叶子计数
bool b = false; //查找是否成功
nodeQueue.push(root); //根节点进入队列
p = root;
while (!nodeQueue.empty()){
if (p->lchild != NULL)
nodeQueue.push(p->lchild); //左孩子进入队列
if (p->rchild != NULL)
nodeQueue.push(p->rchild); //右孩子进入队列
if (p->data == data){ //判断根是否是所查找节点
cout<<endl;
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`" <<endl;
cout<<endl<<"查找成功!" <<endl;
cout<<endl<<"您要查找的节点是:"<<p->data<<endl;
if (p->parent)
cout<<endl <<"它的父节点是:"<<p->parent->data<<endl;
else
cout<<endl <<"它是根节点"<<endl;
if (p->lchild)
cout<<endl <<"它的左孩子节点是:"<<p->lchild->data<<endl;
else
cout<<endl <<"它没有左孩子"<<endl;
if (p->rchild)
cout<<endl <<"它的右孩子节点是:"<<p->rchild->data<<endl;
else
cout<<endl <<"它没有右孩子"<<endl;
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`" <<endl;
b = true;
break;
}
nodeQueue.pop(); //根节点出队列
if (!nodeQueue.empty())
p = nodeQueue.front(); //p重新指向队列第一个元素
}
if (b == false){
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`" <<endl;
cout<<endl<<"查找失败! 您所查找的节点不存在!"<<endl;
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`" <<endl;
}
return b;
}
int BiTree::DepthAt(BiNode *node){ //求深度递归函数,可以直接根据广义表求,但是为了体现二叉树的算法,放弃这个方案,改用递归。
int len;
if (node == NULL){
len = 0;
}
else{ //当左子树比右子树深时,根数就是左子树深度加一,否则是右子树深度加一
int llen = DepthAt(node->lchild);
int rlen = DepthAt(node->rchild);
len = (llen > rlen)? llen + 1: rlen + 1;
}
return len;
}
void BiTree::PreOrderAt(BiNode *node){ //先序遍历的递归算法
cout<<node->data<<' '; //输出根节点
if (node->lchild)
PreOrderAt(node->lchild);
if (node->rchild)
PreOrderAt(node->rchild);
}
void BiTree::InOrderAt(BiNode *node){ //中序遍历递归算法
if (node->lchild)
InOrderAt(node->lchild);
if (node)
cout<<node->data<<' ';
if (node->rchild)
InOrderAt(node->rchild);
}
void BiTree::PostOrderAt(BiNode *node){ //后序遍历递归算法
if (node->lchild)
PostOrderAt(node->lchild);
if (node->rchild)
PostOrderAt(node->rchild);
if (node)
cout<<node->data<<' ';
}
int BiTree::NodeAt(BiNode *node){ //递归求子树的节点数
int num;
if (node == NULL)
num = 0;
else{
num = NodeAt(node->lchild) + NodeAt(node->rchild) + 1;
}
return num;
}
void BiTree::ClearAt(BiNode *node){ //释放子树内存
if (node->lchild != NULL)
ClearAt(node->lchild);
if (node->rchild != NULL)
ClearAt(node->rchild);
if (node != NULL)
delete node;
}
int main(){
BiTree bTree;
string str;
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`"<<endl;
cout<<"请以广义表的形式输入二叉树,按回车键结束:"<<endl;
cin>>str;
bTree.Create(str);
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`"<<endl;
cout<<endl<<"节点数:"<<bTree.Node()<<endl;
cout<<endl<<"叶子数:"<<bTree.Leaf()<<endl;
cout<<endl<<"二叉树深度:"<<bTree.Depth()<<endl;
cout<<endl<<"前序遍历序列:";
bTree.PreOrder();
cout<<endl;
cout<<endl<<"中序遍历序列:";
bTree.InOrder();
cout<<endl;
cout<<endl<<"后序遍历序列:";
bTree.PostOrder();
cout<<endl;
cout<<endl<<"层序遍历序列:";
bTree.LeOrder();
cout<<endl;
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`"<<endl;
char c;
while (c != '1'){
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`"<<endl;
cout<<"请输入您要查找的节点,按回车结束(按1退出):";
cin>>c;
if (c == '1')
break;
bTree.Find(c);
cout<<endl;
}
bTree.Clear();
return 0;
}
/*
测试数据:
A(B(D,E(G,H)),C(I,J(K,L)))
Q
E
1
*/
#include <iostream>
#include <string>
#include <queue>
using namespace std;
class BiNode{ //节点的定义
public:
char data; //用一个整数表示节点的值
BiNode *lchild; //节点的左孩子指针
BiNode *rchild; //节点的右孩子指针
BiNode *parent; //父节点指针
};
class BiTree{ //二叉树的定义
private:
void ClearAt(BiNode *node); //清除子树递归函数
int NodeAt(BiNode *node); //获取子树节点数递归函数
void PostOrderAt(BiNode *node); //后续遍历递归函数
void InOrderAt(BiNode *node); //中序遍历递归函数
void PreOrderAt(BiNode *node); //前序遍历递归函数
int DepthAt(BiNode *node); //求子树的深度
BiNode *root; //二叉树的根节点
string strTable; //保存用于创建二叉树的广义表字符串
public:
void Init(); //初始化为一颗空二叉树
void Create(string str); //由广义表形式串s创建二叉树
void Out(); //按广义表形式输出到控制台
int Depth(); //求二叉树的深度
int Node(); //求节点数
int Leaf(); //求叶子数
void PreOrder(); //前序遍历
void InOrder(); //中序遍历
void PostOrder(); //后序遍历
void LeOrder(); //层序遍历
void Copy(BiTree &biTree); //复制二叉树到biTree
void Clear(); //清空
bool Find(char data); //查找
};
void BiTree::Init(){ //初始化为一颗空二叉树
root = NULL;
}
void BiTree::Create(string str){ //由广义表形式串s创建二叉树
Init(); //初始化二叉树,使根节点为空
strTable = str; //保存这个字符串
char ch; //当前节点的值
int k; //用k作为处理结点的左子树和右子树的标记,k=1处理左子树,k=2处理右子树
BiNode* s[50]; //s数组作为存储二叉树中根结点指针的栈
int top = -1; //top作为s栈的栈顶指针
BiNode *p; //定义p为指向二叉树结点的指针
BiNode *parent = NULL; //指向当前节点的父节点
int count = 0;
ch = str.at(count);
while (count < str.length()){ //每循环一次处理一个读入的字符,直到扫描到'@'字符为止
switch(ch){
case '(':
top++;
s[top] = p;
k = 1;
parent = p; //如果遇到'(',说明上一个节点是后面节点的父节点。用parent保存上一个节点。
break;
case ')':
top--;
break;
case ',':
k = 2;
break;
case ' ':
break;
default:
p = new BiNode;
p->data = ch;
p->parent = parent;
p->lchild = p->rchild = NULL;
if(root == NULL) root=p;
else{
if(k == 1)
s[top]->lchild = p;
else
s[top]->rchild = p;
}
}
count++;
if (count < str.length())
ch = str.at(count);
}
}
void BiTree::Out(){ //按广义表形式输出到控制台
cout<<strTable<<endl;
}
int BiTree::Depth(){ //求二叉树的深度
return DepthAt(root);
}
int BiTree::Node(){ //求节点数
return NodeAt(root);
}
int BiTree::Leaf(){ //求叶子数
queue <BiNode*> nodeQueue; //使用c++标准模板queue,表示一个节点队列
BiNode *p;
int count = 0; //叶子计数
nodeQueue.push(root); //根节点进入队列
p = root;
while (!nodeQueue.empty()){
if (p->lchild != NULL)
nodeQueue.push(p->lchild); //左孩子进入队列
if (p->rchild != NULL)
nodeQueue.push(p->rchild); //右孩子进入队列
if ((p->lchild == NULL) && (p->rchild == NULL)) //判断根是否是叶子节点
count++;
nodeQueue.pop(); //根节点出队列
if (!nodeQueue.empty())
p = nodeQueue.front(); //p重新指向队列第一个元素
}
return count;
}
void BiTree::PreOrder(){ //前序遍历
PreOrderAt(root);
}
void BiTree::InOrder(){ //中序遍历
InOrderAt(root);
}
void BiTree::PostOrder(){ //后序遍历
PostOrderAt(root);
}
void BiTree::LeOrder(){ //层序遍历(用队列实现)
queue <BiNode*> nodeQueue; //使用c++标准模板queue,表示一个节点队列
BiNode *p;
nodeQueue.push(root); //根节点进入队列
p = root;
while (!nodeQueue.empty()){
if (p->lchild != NULL)
nodeQueue.push(p->lchild); //左孩子进入队列
if (p->rchild != NULL)
nodeQueue.push(p->rchild); //右孩子进入队列
cout<<nodeQueue.front()->data<<' '; //输出根节点
nodeQueue.pop(); //根节点出队列
if (!nodeQueue.empty())
p = nodeQueue.front(); //p重新指向队列第一个元素
}
}
void BiTree::Copy(BiTree &biTree){ //复制二叉树到biTree,用本二叉树的广义表字符串构造biTree
biTree.Create(strTable);
}
void BiTree::Clear(){ //清空
ClearAt(root);
}
bool BiTree::Find(char data){ //查找
queue <BiNode*> nodeQueue; //使用c++标准模板queue,表示一个节点队列
BiNode *p;
int count = 0; //叶子计数
bool b = false; //查找是否成功
nodeQueue.push(root); //根节点进入队列
p = root;
while (!nodeQueue.empty()){
if (p->lchild != NULL)
nodeQueue.push(p->lchild); //左孩子进入队列
if (p->rchild != NULL)
nodeQueue.push(p->rchild); //右孩子进入队列
if (p->data == data){ //判断根是否是所查找节点
cout<<endl;
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`" <<endl;
cout<<endl<<"查找成功!" <<endl;
cout<<endl<<"您要查找的节点是:"<<p->data<<endl;
if (p->parent)
cout<<endl <<"它的父节点是:"<<p->parent->data<<endl;
else
cout<<endl <<"它是根节点"<<endl;
if (p->lchild)
cout<<endl <<"它的左孩子节点是:"<<p->lchild->data<<endl;
else
cout<<endl <<"它没有左孩子"<<endl;
if (p->rchild)
cout<<endl <<"它的右孩子节点是:"<<p->rchild->data<<endl;
else
cout<<endl <<"它没有右孩子"<<endl;
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`" <<endl;
b = true;
break;
}
nodeQueue.pop(); //根节点出队列
if (!nodeQueue.empty())
p = nodeQueue.front(); //p重新指向队列第一个元素
}
if (b == false){
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`" <<endl;
cout<<endl<<"查找失败! 您所查找的节点不存在!"<<endl;
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`" <<endl;
}
return b;
}
int BiTree::DepthAt(BiNode *node){ //求深度递归函数,可以直接根据广义表求,但是为了体现二叉树的算法,放弃这个方案,改用递归。
int len;
if (node == NULL){
len = 0;
}
else{ //当左子树比右子树深时,根数就是左子树深度加一,否则是右子树深度加一
int llen = DepthAt(node->lchild);
int rlen = DepthAt(node->rchild);
len = (llen > rlen)? llen + 1: rlen + 1;
}
return len;
}
void BiTree::PreOrderAt(BiNode *node){ //先序遍历的递归算法
cout<<node->data<<' '; //输出根节点
if (node->lchild)
PreOrderAt(node->lchild);
if (node->rchild)
PreOrderAt(node->rchild);
}
void BiTree::InOrderAt(BiNode *node){ //中序遍历递归算法
if (node->lchild)
InOrderAt(node->lchild);
if (node)
cout<<node->data<<' ';
if (node->rchild)
InOrderAt(node->rchild);
}
void BiTree::PostOrderAt(BiNode *node){ //后序遍历递归算法
if (node->lchild)
PostOrderAt(node->lchild);
if (node->rchild)
PostOrderAt(node->rchild);
if (node)
cout<<node->data<<' ';
}
int BiTree::NodeAt(BiNode *node){ //递归求子树的节点数
int num;
if (node == NULL)
num = 0;
else{
num = NodeAt(node->lchild) + NodeAt(node->rchild) + 1;
}
return num;
}
void BiTree::ClearAt(BiNode *node){ //释放子树内存
if (node->lchild != NULL)
ClearAt(node->lchild);
if (node->rchild != NULL)
ClearAt(node->rchild);
if (node != NULL)
delete node;
}
int main(){
BiTree bTree;
string str;
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`"<<endl;
cout<<"请以广义表的形式输入二叉树,按回车键结束:"<<endl;
cin>>str;
bTree.Create(str);
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`"<<endl;
cout<<endl<<"节点数:"<<bTree.Node()<<endl;
cout<<endl<<"叶子数:"<<bTree.Leaf()<<endl;
cout<<endl<<"二叉树深度:"<<bTree.Depth()<<endl;
cout<<endl<<"前序遍历序列:";
bTree.PreOrder();
cout<<endl;
cout<<endl<<"中序遍历序列:";
bTree.InOrder();
cout<<endl;
cout<<endl<<"后序遍历序列:";
bTree.PostOrder();
cout<<endl;
cout<<endl<<"层序遍历序列:";
bTree.LeOrder();
cout<<endl;
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`"<<endl;
char c;
while (c != '1'){
cout<<endl<<"`~`~`~`~`~`~`~`~`~`~`"<<endl;
cout<<"请输入您要查找的节点,按回车结束(按1退出):";
cin>>c;
if (c == '1')
break;
bTree.Find(c);
cout<<endl;
}
bTree.Clear();
return 0;
}
/*
测试数据:
A(B(D,E(G,H)),C(I,J(K,L)))
Q
E
1
*/