您的位置:首页 > 其它

二叉树基本操作实现

2013-03-08 20:40 453 查看
// BiTree_02.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

/****************************************************************************/
/*  1、问题描述:很多涉及二叉树的操作的算法都是以二叉树的遍历操作为基础的。*/
/*  编写程序,对一棵给定的二叉树进行先、中、后三种次序的遍历。              */
/*  2、基本要求:以二叉链表为存储结构,实现二叉树的先、中、后三种次序的递  */
/*  归和非递归遍历。                                                        */
/*  3、测试数据:以教科书图6.9的二叉树为例。                               */
/*  4、实现提示:                                                          */
/*    (1)、设二叉树的结点不超过30个,且每个结点的数据均为字符,这样可  */
/*  利用先序遍历序列作为输入顺序创建二叉树链表存储结构。                    */
/*    (2)、也可利用完全二叉树在顺序存储中的特性,创建二叉树的存储结构,*/
/*  此时,二叉树中结点数据的类型不受限制。                                  */
/*  5、选作内容:                                                          */
/*    (1)、借助队列,实现二叉树的层序遍历。                            */
/*    (2)、按凹入表或树形打印所遍历的二叉树。                          */
/****************************************************************************/
#include<iostream>
#include<fstream>
#include<string>
#include<stack>
#include<stdlib.h>
//#include<stdio.h>
//#include<malloc.h>
using namespace std;
//--------------------------------------------------
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef char TElemtype;
const int MaxLength = 30;//二叉树的结点不超过30个
typedef struct BiTNode{//二叉树结点结构
TElemtype data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//--------------------------------------------------
class BinaryTree{
private:
BiTree T;
public:
int CreateBiTree(BiTree &T,ifstream &in);
//递归遍历
void PreOrder(BiTree &T);
void InOrder(BiTree &T);
void PostOrder(BiTree &T);
//层序遍历
void LevelOrder(BiTree T);
//非递归遍历
void RePreOrder(BiTree &T);
void ReInOrder(BiTree &T);
void RePostOrder(BiTree &T);

bool Complete(BiTree T);
int Depth(BiTree T);
int Countleaf(BiTree T);
int Countleafs(BiTree T);
};//BinaryTree
//--------------------------------------------------
void main(){
ofstream out("data.txt");
/*  if(out){
for(char i = 65; i < 70; i++)
out << i;// << '#' << char(i + 7);
out << "###############";
}
*/
//  out << "AB##C##";
//  out << "ABC##D##EF##G##";
//  out << "ABCD##E##FG##H##IJK##L##MN##O##";
out << "ABCD##E##FG##H##IJK##L##MN####";
out.close();

cout<<"按先序序列输入二叉树中结点的值,如:\n-+a##*b##-c##d##/e##f##\n";
ifstream in("data.txt");
BinaryTree bt;
BiTree tree;
bt.CreateBiTree(tree,in);
in.close();
cout<<"二叉树创建完成!\n";
cout<<"----------------\n";

cout<<"递归遍历:\n";
cout<<"先序遍历二叉树:\n";
bt.PreOrder(tree);
cout<<endl;

cout<<"中序遍历二叉树:\n";
bt.InOrder(tree);
cout<<endl;

cout<<"后序遍历二叉树:\n";
bt.PostOrder(tree);
cout<<endl;

cout<<"----------------\n";

cout<<"非递归遍历:\n";
cout<<"先序遍历二叉树:\n";
bt.RePreOrder(tree);
cout<<endl;

cout<<"中序遍历二叉树:\n";
bt.ReInOrder(tree);
cout<<endl;

cout<<"后序遍历二叉树:\n";
bt.RePostOrder(tree);
cout<<endl;

cout<<"----------------\n";
cout<<"层序遍历二叉树是否为完全二叉树:";
if(bt.Complete(tree))
cout<<"是\n";
else
cout<<"不是\n";

cout<<"此二叉树的深度为:"<<bt.Depth(tree)<<endl;
cout<<"此二叉树的总结点个数为:"<<bt.Countleafs(tree)<<endl;
cout<<"此二叉树的叶子结点个数为:"<<bt.Countleaf(tree)<<endl;
}
//--------------------------------------------------
int BinaryTree::CreateBiTree(BiTree &T,ifstream &in){
//按先序序列输入二叉树中结点的值,空格字符表示空树,
//构造二叉树表表示的二叉树T;
char ch;
in>>ch;
if(ch == '#') T = NULL;
else{
T = (BiTNode*)malloc(sizeof(BiTNode));
if(T == NULL) return ERROR;//*/if(!(T = new BiTNode)) exit(OVERFLOW);
T -> data = ch;//生成根节点
int temp = CreateBiTree(T -> lchild,in) + CreateBiTree(T -> rchild,in);//构造右子树
//       CreateBiTree(T -> lchild,in)//构造左子树
//       CreateBiTree(T -> rchild,in);//构造右子树
}//else
return OK;
}//CreateBiTree
//--------------------------------------------------
void BinaryTree::PreOrder(BiTree &T){//递归函数:先序遍历以T为根的二叉树
if(T != NULL){//递归结束条件
cout<<T -> data<<" ";//访问根节点
PreOrder(T -> lchild);//先序遍历根节点的左子树
PreOrder(T -> rchild);//先序遍历根节点的右子树

}
}//PreOrder
//--------------------------------------------------
void BinaryTree::InOrder(BiTree &T){//递归函数:中序遍历以T为根的二叉树
if(T != NULL){//递归结束条件
InOrder(T -> lchild);//中序遍历根节点的左子树
cout<<T -> data<<" ";//访问根节点
InOrder(T -> rchild);//中序遍历根节点的右子树
}
}//InOrder
//--------------------------------------------------
void BinaryTree::PostOrder(BiTree &T){//递归函数:后序遍历以T为根的二叉树
if(T != NULL){//递归结束条件
PostOrder(T -> lchild);//后序遍历根节点的左子树
PostOrder(T -> rchild);//后序遍历根节点的右子树
cout<<T -> data<<" ";//访问根节点
}
}//PostOrder
//--------------------------------------------------
void BinaryTree::RePreOrder(BiTree &T){//非递归函数:先序遍历以T为根的二叉树
stack<BiTree> s;
s.push(T);//根指针进栈
while(!s.empty()){
BiTree b = s.top();
if(!s.empty()){//访问结点
b = s.top();
s.pop();
if(b -> data == NULL) cout<<"error";
else
cout<<b -> data<<" ";
}//if
if(b -> rchild) s.push(b -> rchild); //若右孩子存在,则入栈
if(b -> lchild) s.push(b -> lchild); //若左孩子存在,则入栈
}//while
}//RePreOrder
//--------------------------------------------------
void BinaryTree::ReInOrder(BiTree &T){//非递归函数:中序遍历以T为根的二叉树
stack<BiTree> s;
s.push(T);//根指针进栈
while(!s.empty()){
BiTree b = s.top();
while(b){//向左走到尽头
s.push(b -> lchild);
b = s.top();
}//while
s.pop();//空指针退栈
if(!s.empty()){//访问结点,向右一步
b = s.top();
s.pop();
if(b -> data == NULL) cout<<"error";
else
cout<< b -> data<<" ";
s.push(b -> rchild);
}//if
}//while
}//ReInOrder
//--------------------------------------------------
void BinaryTree::RePostOrder(BiTree &T){//非递归函数:后序遍历以T为根的二叉树
stack<BiTree> s;
BiTree r,p;//使用r标记访问过的右子树
p = T;
while(p||!s.empty())
{
if(p)
{
s.push(p);
p = p -> lchild;
}//if
else
{
p = s.top();
if(p -> rchild && p -> rchild != r)
{
p = p -> rchild;
s.push(p);
p = p-> lchild;
}
else
{
s.pop();
cout<<p->data<<" ";
r = p;
p = NULL;
}
}//else
}//while
}//RePostOrder
//--------------------------------------------------
void BinaryTree::LevelOrder(BiTree T){//借助队列,层序遍历
BiTree Q[MaxLength];
int front = 0;
int rear = 0;
BiTree p;
if(T){//根节点入队
Q[rear] = T;
rear = (rear + 1) % MaxLength;
}
while(front != rear){
p = Q[front];
cout<<p -> data<<" ";
front = (front + 1) % MaxLength;//队头元素出队

if(p -> lchild){//左孩子不为空,入队
Q[rear] = p -> lchild;
rear = (rear + 1) % MaxLength;
}
if(p -> rchild){//右孩子不为空,入队
Q[rear] = p -> rchild;
rear = (rear + 1) % MaxLength;
}
}//while
}//LevelOrder
//--------------------------------------------------
bool BinaryTree::Complete(BiTree T){//是否为完全二叉树
BiTree Q[MaxLength];
int front = 0;
int rear = 0;
BiTree p;

if(T == NULL)return true;//!T 即T == NULL
else{
Q[rear] = T;//根节点入队
rear = (rear + 1) % MaxLength;
while(front != rear){//队列不空
p = Q[front];
front = (front + 1) % MaxLength;//队头元素出队

if(p){
Q[rear] = p -> lchild;//左孩子入队
rear = (rear + 1) % MaxLength;

Q[rear] = p -> rchild;//右孩子入队
rear = (rear + 1) % MaxLength;
}//if
else{
while(front != rear){//队列不空
p = Q[front];
if(p) return false;
return true;
}//while
}//else
}//while
return true;//队列空则返回是
}//else
}//Complete
//--------------------------------------------------
int BinaryTree::Depth(BiTree T){
int depthval,depthleft,depthright;
if(T == NULL) depthval = 0;
else{
depthleft = Depth(T -> lchild);
depthright = Depth(T -> rchild);
depthval = 1 + (depthleft > depthright ? depthleft : depthright);
}//else
return depthval;
}//Depth
//--------------------------------------------------
int BinaryTree::Countleaf(BiTree T){//二叉树的叶子结点个数
int m,n;
if(!T) return 0;
if(!T -> lchild && !T -> rchild) return 1;
else {
m = Countleaf(T -> lchild);
n = Countleaf(T -> rchild);
return(m + n);
}//else
}//Countleaf
//--------------------------------------------------
int BinaryTree::Countleafs(BiTree T){//二叉树的总结点个数
int m,n;
if(!T) return 0;
if(!T -> lchild && !T -> rchild) return 1;
else {
m = Countleafs(T -> lchild);
n = Countleafs(T -> rchild);
return(m + n + 1);
}//else
}//Countleafs
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二叉树