c++实现二叉树的构建与遍历
二叉树数据示例:a(b(,d),c(e(g),f))
代码:
// 二叉树.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include<fstream>
#include<stdio.h>
using namespace std;
#define MaxSize 100
char gnodeString[100];
class node //结点类
{
public:
node(char data, int deep, node *initf, node *initl, node *initr);
char data; //数据
int deep; //所在深度
node *lchild; //指向左儿子
node *rchild; //指向右儿子
node *father; //指向父结点
};
node::node(char data, int deep, node *initf, node *initl, node *initr)
{
this->data = data;
this->deep = deep;
this->father = initf;
this->lchild = initl;
this->rchild = initr;
} //方便后面的代码初始化node
class btree //二叉树类
{
public:
btree();
~btree();
void createbtree(); //二叉树建立
void visit(node *searchp);
node *getroot();
void preorder(node * searchp); //先跟遍历
void inorder(node * searchp); //中跟遍历
void postorder(node * searchp); //后跟遍历
void nrpreorder(node * searchp); //非递归先跟遍历
void nrinorder(node * searchp); //非递归中跟遍历
void nrpostorder(node * searchp); //非递归后跟遍历
private:
node * root;
node *workinp; //工作指针
node *newnode;
};
btree::btree()
{
}
btree::~btree()
{
}
void btree::createbtree() //二叉树的构建
{
root = new node(gnodeString[0], 1, NULL, NULL, NULL);
workinp = root;
for (int i = 1; gnodeString[i] != '\0'; i++)
{
char choice = gnodeString[i];
switch (choice)
{
case '(':
if (gnodeString[i + 1] == ',')
{
i = i + 2;
newnode = new node(gnodeString[i], workinp->deep + 1, NULL, NULL, NULL);
workinp->rchild = newnode;
newnode->father = workinp;
i++;
}
else
{
i++;
newnode = new node(gnodeString[i], workinp->deep + 1, NULL, NULL, NULL); //新建结点
workinp->lchild = newnode; //建立父子关系
newnode->father = workinp; //建立父子关系
workinp = workinp->lchild; //工作指针移动
}
break;
case ',':
i++;
workinp = workinp->father;
newnode = new node(gnodeString[i], workinp->deep + 1, NULL, NULL, NULL);
workinp->rchild = newnode;
newnode->father = workinp;
workinp = workinp->rchild;
break;
case ')':
workinp = workinp->father;
break;
}
}
}
node * btree::getroot()
{
return root;
}
void btree::visit(node * searchp)
{
cout << " " << searchp->data;
}
void btree::preorder(node * searchp)
{
if (searchp != NULL)
{
visit(searchp);
preorder(searchp->lchild);
preorder(searchp->rchild);
}
}
void btree::inorder(node * searchp)
{
if (searchp!=NULL)
{
inorder(searchp->lchild);
visit(searchp);
inorder(searchp->rchild);
}
}
void btree::postorder(node * searchp)
{
if (searchp != NULL)
{
postorder(searchp->lchild);
postorder(searchp->rchild);
visit(searchp);
}
}
void btree::nrpreorder(node * searchp)
{
node *stack[MaxSize], *pnow; //启用栈的思想来处理
int top = 0;
pnow = searchp;
while (!(pnow == NULL&&top == 0) )
{
while (pnow != NULL)
{
visit(pnow);
stack[top] = pnow;
top++;
pnow = pnow->lchild;
} //依次移向左儿子
if (top <= 0)
return;
else
{
top--;
pnow = stack[top];
pnow = pnow->rchild;
} //依次出栈并指向右儿子
}
}
void btree::nrinorder(node * searchp)
{
node *stack[MaxSize], *pnow;
int top = 0;
pnow = searchp;
while (!(pnow == NULL && top == 0))
{
while (pnow != NULL)
{
stack[top] = pnow;
top++;
pnow = pnow->lchild;
}
if (top <= 0)
return;
else
{
top--;
pnow = stack[top];
visit(pnow);
pnow = pnow->rchild;
}
}
}
void btree::nrpostorder(node * searchp)
{
struct stackdata
{
node *link;
int flag;
};
stackdata stack[MaxSize];
node *pnow;
int top = -1, sign;
pnow = searchp;
while (!(pnow == NULL && top == -1))
{
if (pnow != NULL)
{
top++;
stack[top].link = pnow;
stack[top].flag = 1;
pnow = pnow->lchild;
}
else
{
pnow = stack[top].link;
sign = stack[top].flag;
top--;
if (sign == 1)
{
top++;
stack[top].link = pnow;
stack[top].flag = 2;
pnow = pnow->rchild;
}
else
{
visit(pnow);
pnow = NULL;
}
}
}
return;
}
void readData()
{
ifstream in("Data.txt");
char ch;
int index = 0;
if (in)
{
while (!in.eof())
{
in >> ch;
gnodeString[index++] = ch;
}
gnodeString[--index] = '\0';
}
else //没有该文件
{
cout << "no such file" << endl;
}
}
int main()
{
readData();
cout << gnodeString;
btree b = btree();
b.createbtree();
cout << endl << "递归先根遍历如下:" << endl;
b.preorder(b.getroot());
cout << endl << "递归中根遍历如下:" << endl;
b.inorder(b.getroot());
cout << endl << "递归后根遍历如下:" << endl;
b.postorder(b.getroot());
cout << endl << "非递归先根遍历如下:" << endl;
b.nrpreorder(b.getroot());
cout << endl << "非递归中根遍历如下:" << endl;
b.nrinorder(b.getroot());
cout << endl << "非递归后根遍历如下:" << endl;
b.nrpostorder(b.getroot());
cout << endl;
system("pause");
return 0;
}