数据结构二叉树类的实现
//类的头文件
#ifndef BINTREE_H_INCLUDED
#define BINTREE_H_INCLUDED
#include<iostream>
using namespace std;
class BinTreeNode{
private:
BinTreeNode *left, *right;
char c;
public:
BinTreeNode();
BinTreeNode(BinTreeNode* left, BinTreeNode* right, char ch);
~BinTreeNode();
BinTreeNode* GetLeft()const;
void SetLeft(BinTreeNode* t);
BinTreeNode* GetRight()const;
void SetRight(BinTreeNode* t);
char GetC()const;
void SetC(char c);
};
class BinTree{
private:
BinTreeNode *root;
public:
BinTree(BinTreeNode *t):root(t) {}
virtual ~BinTree();///析构函数删除整棵树
BinTreeNode* CreateBinTree(FILE *fp);
///在以t为根结点的子树中搜索结点p的父节点
BinTreeNode* Father(BinTreeNode* t, BinTreeNode* p);
///在以结点t为根结点的子树中查找data域为item的结点
BinTreeNode* Find(BinTreeNode* t, char ch);
void del(BinTreeNode *t);
void DelSubtree(BinTreeNode* t);///从树中删除结点t及其左右子树
void PreOrder(const BinTreeNode* t)const;///先根遍历,非递归
void InOrder(const BinTreeNode* t)const;///中根遍历,非递归版本的
void PostOrder(const BinTreeNode* t)const;///后根遍历,递归版本的
void LevelOrder(BinTreeNode* t)const;///层次遍历
///将node结点插入到t的子结点,flag为真时,插入到左子结点,flag为false时插入到右子结点
void Insert(BinTreeNode* t, char ch, bool flag);
BinTreeNode* GetRoot();
void SetRoot(BinTreeNode* t);
bool isEmpty();
};
#endif // BINTREE_H_INCLUDED
//类的定义文件
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
#include"BinTree.h"
using namespace std;
BinTreeNode::BinTreeNode() {}
BinTreeNode::BinTreeNode(BinTreeNode* l, BinTreeNode* r, char ch) {
left = l;
right = r;
c = ch;
}
BinTreeNode::~BinTreeNode() {
}
char BinTreeNode::GetC()const {
return c;
}
BinTreeNode* BinTreeNode::GetLeft()const {
return left;
}
BinTreeNode* BinTreeNode::GetRight()const {
return right;
}
void BinTreeNode::SetC(char ch) {
c = ch;
}
void BinTreeNode::SetLeft(BinTreeNode* t){
left = t;
}
void BinTreeNode::SetRight(BinTreeNode* t) {
right = t;
}
BinTree::~BinTree() {
this->DelSubtree(root);
}
BinTreeNode* BinTree::CreateBinTree(FILE *fp) {
BinTreeNode* t;
char data;
fscanf(fp, "%c", &data);
if(data == '^') {
t = NULL;
return t;
} else {
if(!(t = new BinTreeNode(NULL, NULL, data))) {
return NULL;
}
t->SetLeft(CreateBinTree(fp));
t->SetRight(CreateBinTree(fp));
return t;
}
}
BinTreeNode* BinTree::Father(BinTreeNode* t, BinTreeNode* p) {
BinTreeNode* f = NULL;
if(t == NULL || p == NULL) {
return NULL;
}
if(p == root) {
return NULL;
}
if(t->GetLeft() == p || t->GetRight() == p) {
return t;
} else {
f = Father(t->GetLeft(), p);
if(f != NULL) {
return f;
} else {
return Father(t->GetRight(), p);
}
}
}
BinTreeNode* BinTree::Find(BinTreeNode* t, char ch) {
BinTreeNode *node = NULL;
if(t == NULL) {
return NULL;
}
if( t->GetC() == ch) {
return t;
} else {
node = Find(t->GetLeft(), ch);
if(node != NULL) {
return node;
} else {
return Find(t->GetRight(), ch);
}
}
}
void BinTree::del(BinTreeNode *t) {
if(t != NULL) {
del(t->GetLeft());
del(t->GetRight());
delete t;
}
}
void BinTree::DelSubtree(BinTreeNode *t) {
if(t == NULL) {
return;
}
if(t == root) {
del(t);
root = NULL;
return;
}
BinTreeNode *f, *p;
p = t;
f = Father(root, p);
if(f) {
if(f->GetLeft() == p) {
f->SetLeft(NULL);
}
if(f->GetRight() == p) {
f->SetRight(NULL);
}
}
del(p);
}
void BinTree::PreOrder(const BinTreeNode* t) const {
if(t == NULL) {
return;
}
cout<<t->GetC();
PreOrder(t->GetLeft());
PreOrder(t->GetRight());
}
void BinTree::InOrder(const BinTreeNode* t) const {
if(t == NULL) {
return;
}
InOrder(t->GetLeft());
cout<<t->GetC();
InOrder(t->GetRight());
}
void BinTree::PostOrder(const BinTreeNode* t) const {
// cout<<"hello"<<endl;
if(t == NULL) {
return;
}
PostOrder(t->GetLeft());
PostOrder(t->GetRight());
cout<<t->GetC();
}
void BinTree::LevelOrder(BinTreeNode* t) const {
queue<BinTreeNode*>q;
if(t != NULL) {
q.push(t);
}
BinTreeNode *node;
while(!q.empty()) {
node = q.front();
q.pop();
cout << node->GetC();
if(node->GetLeft() != NULL) {
q.push(node->GetLeft());
}
if(node->GetRight() != NULL) {
q.push(node->GetRight());
}
}
}
BinTreeNode* BinTree::GetRoot() {
return root;
}
void BinTree::SetRoot(BinTreeNode* t) {
root = t;
}
bool BinTree::isEmpty() {
if(root == NULL) {
return true;
}
return false;
}
void BinTree::Insert(BinTreeNode* t, char ch, bool flag) {
BinTreeNode *r = Find(root, ch);
if(r == NULL) {
cout<<"未找到父节点t"<<endl;
return;
} else if(flag) {
r->SetLeft(t);
cout<<"插入成功"<<endl;
} else {
r->SetRight(t);
cout<<"插入成功"<<endl;
}
}
//用户界面
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include"BinTree.h"
using namespace std;
int main() {
cout<<"开始创建二叉树"<<endl;
cout<<"请按照输入所创建数的先根遍历的序列"<<endl;
BinTreeNode *root;
BinTree *tree = new BinTree(root);
FILE *fp = fopen("tree.txt", "r");
//char num[100];
root = tree->CreateBinTree(fp);
// fscanf(fp, "%s", num);
fclose(fp);
tree->SetRoot(root);
cout<<"二叉树已经创建好"<<endl;
cout<<tree->GetRoot()->GetC()<<endl;
cout<<"请选择操作"<<endl;
cout<<"0.退出\n1.查找值为item的结点\n2.查找结点p的父节点\n3.从树中删除结点t及其左右子树"<<endl;
cout<<"4.先根遍历二叉树\n5.中根遍历二叉树\n6.后根遍历二叉树\n7.层次遍历二叉树\n8.判断树是否为空"<<endl;
cout<<"9.向树中插入一个结点"<<endl;
int choose;
BinTreeNode *node, *temp;
char ch;
int side;
cin>>choose;
while(choose) {
switch(choose) {
case 1:
cout<<"请输入所需要查找的结点的值";
cin>>ch;
node = tree->Find(tree->GetRoot(), ch);
if(node != NULL) {
cout<<"找到结点"<<endl;
} else {
cout<<"未找到结点"<<endl;
}
break;
case 2:
cout<<"查找结点p的父节点,请输入结点p的值"<<endl;
cin>>ch;
node = tree->Find(tree->GetRoot(), ch);
temp = tree->Father(tree->GetRoot(), node);
if(temp != NULL) {
cout<<"值为"<<node->GetC()<<"的结点的父结点的值为"<<temp->GetC()<<endl;
} else {
cout<<"未找到p的父节点"<<endl;
}
break;
case 3:
cout<<"请输出要删除子树的根节点的值"<<endl;
cin>>ch;
node = tree->Find(tree->GetRoot(), ch);
if(node != NULL) {
cout<<"找到该结点,正在进行删除处理"<<endl;
if(node == tree->GetRoot()) {
cout<<"就是根节点"<<endl;
}
tree->DelSubtree(node);
}
break;
case 4:
cout<<"二叉树的先根遍历的序列为:";
tree->PreOrder(tree->GetRoot());
cout<<endl;
break;
case 5:
cout<<"二叉树的中根遍历的序列为:";
tree->InOrder(tree->GetRoot());
cout<<endl;
break;
case 6:
cout<<"二叉树的后根遍历的序列为:";
tree->PostOrder(tree->GetRoot());
cout<<endl;
break;
case 7:
cout<<"二叉树的层次遍历的序列为:";
tree->LevelOrder(tree->GetRoot());
cout<<endl;
break;
case 8:
if(tree->isEmpty()) {
cout<<"树为空"<<endl;
} else {
cout<<"树非空"<<endl;
}
break;
case 9:
cout<<"请输入所要插入结点的值"<<endl;
cin>>ch;
temp = new BinTreeNode(NULL, NULL, ch);
cout<<"请输入所要插入的结点的父节点的值"<<endl;
cin>>ch;
cout<<"请选择是插在左子树还是右子树,1表示左,0表示右"<<endl;
cin>>side;
tree->Insert(temp, ch, side);
}
cout<<"请选择操作"<<endl;
cout<<"0.退出\n1.查找值为item的结点\n2.查找结点p的父节点\n3.从树中删除结点t及其左右子树"<<endl;
cout<<"4.先根遍历二叉树\n5.中根遍历二叉树\n6.后根遍历二叉树\n7.层次遍历二叉树\n8.判断树是否为空"<<endl;
cout<<"9.向树中插入一个结点"<<endl;
cin>>choose;
}
return 0;
}
说明按照先根遍历序列输入一颗扩充二叉树,'^'是表示空节点的
测试数据
AB^C^D^^EF^^GH^IJ^^^^
对应的树为