⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 二叉树建立与遍历.cpp

📁 二叉树建立与遍历源代码
💻 CPP
字号:
//程序用法:本程序二叉树的构造过程采用广义表作为输入,预先把节点信息以广义表字符串形式存储在文本
//文件中,程序运行首先从文件中读出节点信息构造二叉树。
//注意:文件中每一个字母代表一个节点元素值;
//      每个根结点作为由子树构成的表的名字放在前面;
//      每个结点的左孩子与右孩子用逗号隔开,若只有右孩子而无左孩子,逗号不能省略;
//      整个广义表以@作为结尾!!!,切记。
#include<iostream>
#include<fstream>
#include<limits>
#include<queue>//为了避免代码过于冗余,在此不自定义队列类,使用系统容器代替。
#include<stack>//同上
using namespace std;

char read(char *A)//从字符数组读取字符
{
	static count=0;
	return A[count++];
}

//树结点类:
class BinaryTree;
class BinTreeNode{
friend class BinaryTree;
private:
	BinTreeNode *leftChild,*rightChild;//左右孩子指针
	char data;//节点元素
public:
	BinTreeNode():leftChild(NULL),rightChild(NULL){}
	BinTreeNode(char d,BinTreeNode *lp=NULL,
		BinTreeNode *rp=NULL):data(d),leftChild(lp),rightChild(rp){}
	char GetData()//获取节点元素
	{
		return data;
	}
	BinTreeNode *GetLeftChild()//取得左孩子指针
	{
		return leftChild;
	}
	BinTreeNode *GetRightChild()//取得右孩子指针
	{
		return rightChild;
	}
	void SetData(char d)//设置节点元素值
	{
		data=d;
	}
	void SetLeftChild(BinTreeNode *p)//设置左孩子指针
	{
		leftChild=p;
	}
	void SetRightChild(BinTreeNode *p)//设置右孩子指针
	{
		rightChild=p;
	}
};

//二叉树链表类
class BinaryTree{
private:
	BinTreeNode *root;//根结点
	void destroy(BinTreeNode *p);//销毁结点P
	void PreOrderTravers(BinTreeNode *r);//前序遍历
	void InOrderTravers(BinTreeNode *r);//中序遍历
	void PostOrderTravers(BinTreeNode *r);//后序遍历
	int length(BinTreeNode *n);//求树的深度
public:
	BinaryTree():root(NULL){}
	BinaryTree(char d)
	{
		root=new BinTreeNode(d);
	}
	virtual~BinaryTree()
	{
		destroy(root);
	}
    bool IsEmpty(){return root==NULL? true:false;}//判断树非空
    void build(char *A);//建立二叉树
	int length(){return length(root);};//求树的深度接口
    void PreOrderTravers()//前序遍历接口
	{
		PreOrderTravers(root);
	}
	void InOrderTravers()//中序遍历接口
	{
		InOrderTravers(root);
	}
	void PostOrderTravers()//后序遍历接口
	{
		PostOrderTravers(root);
	}
	void LevelOrderTravers();//层次遍历
};
//成员函数实现
void BinaryTree::build(char *A)//建立二叉树,由广义表输入
{
	stack<BinTreeNode*> t;
	BinTreeNode *p;
	int flag;
    do
	{
		char ch=read(A);
		switch(ch)
		{
		case '@':return;
		case '(':{t.push(p);flag=1;}break;
		case ')':t.pop();break;
		case ',':flag=2;break;
		default:{
			        p=new BinTreeNode(ch);
                    if(root==NULL)
					{
						root=p;
					}
					else
					{
						if(flag==1)
						{
							t.top()->SetLeftChild(p);
						}
						else
						{
							t.top()->SetRightChild(p);
						}
					}
				}
			break;
		}
	}while(true);
}
int BinaryTree::length(BinTreeNode *n)//求树深度
{
	if(n==NULL)
	{
		return 0;
	}
	else
	{
		int lclen=length(n->GetLeftChild());
		int rclen=length(n->GetRightChild());
		if(lclen<rclen)
			return rclen+1;
		else
			return lclen+1;
	}
}
void BinaryTree::destroy(BinTreeNode *p)//销毁二叉树
{
	if(p!=NULL)
	{
		destroy(p->GetLeftChild());
		destroy(p->GetRightChild());
		delete p;
	}
}
//前序遍历
void BinaryTree::PreOrderTravers(BinTreeNode *r)
{
	if(r!=NULL)
	{
		cout<<r->GetData()<<" ";
		PreOrderTravers(r->GetLeftChild());
		PreOrderTravers(r->GetRightChild());
	}
}
//中序遍历
void BinaryTree::InOrderTravers(BinTreeNode *r)
{
	if(r!=NULL)
	{
		InOrderTravers(r->GetLeftChild());
		cout<<r->GetData()<<" ";
		InOrderTravers(r->GetRightChild());
	}
}
//后序遍历
void BinaryTree::PostOrderTravers(BinTreeNode *r)
{
	if(r!=NULL)
	{
		PostOrderTravers(r->GetLeftChild());
		PostOrderTravers(r->GetRightChild());
		cout<<r->GetData()<<" ";}
}
//层次遍历
void BinaryTree::LevelOrderTravers()
{
	queue<BinTreeNode*> q;
	BinTreeNode *p=root;
	if(p)
		q.push(p);
	while(!q.empty())
	{
		p=q.front();
		cout<<p->GetData()<<" ";
		if(p->GetLeftChild())
			q.push(p->GetLeftChild());
		if(p->GetRightChild())
			q.push(p->GetRightChild());
		q.pop();
	}
}

void Reset()//输入异常处理函数
{
	cout<<"输入非数字字符,请重输:\n";
	cout<<std::flush;
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n' );
}
//主函数
void main()
{
	BinaryTree BTree;
	char *A=new char[30];
	ifstream file("node.txt",ios::in);
	if(!file)
	{
		cout<<"节点文件打开失败,请先配置好二叉树的节点文件!";
		return;
	}
	file.getline(A,30);
	file.close(); 
	BTree.build(A);
	cout<<"二叉树构造完毕!"<<endl;
	do
	{
		cout<<endl;
		cout<<"\t\t\t****请选择操作****\n";
        cout<<"\t\t\t****1.先根遍历****\n";
	    cout<<"\t\t\t****2.中根遍历****\n";
        cout<<"\t\t\t****3.后根遍历****\n";
        cout<<"\t\t\t****4.层次遍历****\n";
     	cout<<"\t\t\t****5.树的深度****\n";
    	cout<<"\t\t\t****6.退出模拟****\n";
    	cout<<"请选择:";
	    int s;//选择
		while(!(cin>>s))
			 Reset();
	    switch(s)
		{
     	case 1:cout<<endl<<"先根遍历结果:"<<endl;BTree.PreOrderTravers();break;
	    case 2:cout<<endl<<"中根遍历结果:"<<endl;BTree.InOrderTravers();break;
	    case 3:cout<<endl<<"后根遍历结果:"<<endl;BTree.PostOrderTravers();break;
        case 4:cout<<endl<<"层次遍历结果:"<<endl;BTree.LevelOrderTravers();break;
		case 5:cout<<endl<<"该二叉树的深度为:";cout<<BTree.length();break;
		case 6:return;
     	default:cout<<"请正确选择!\n";break;
		}
	}while(true);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -