#include<iostream>
#include<stack>
#include<malloc.h>
using namespace std;
#define MaxSize 100
//二叉树结点信息
struct TreeNode {
char data;
TreeNode *lchild, *rchild;
bool left=false;
bool right = false;
};
struct TreeNode_ {
int value;
TreeNode_ *lchild, *rchild;
};
//线索二叉树节点信息
struct Node {
char data;
Node *lchild, *rchild;
int ltag, rtag;
} ;
Node *pre;
//先序遍历创建二叉树递归实现
void CreateBiTree(TreeNode *&root) {
char ch;
cin >> ch;
if(ch!= '*') {
root=new TreeNode;
root->data=ch;
CreateBiTree(root->lchild);
CreateBiTree (root->rchild);
} else root=NULL;
}
//先序遍历
void preorder(TreeNode *p) {
if(p!=NULL) {
cout<<p->data<<" ";
preorder(p->lchild);
preorder(p->rchild);
}
}
//中序遍历
void inorder(TreeNode *p) {
if (p) {
inorder (p->lchild);
cout<<p->data<<" ";
inorder (p->rchild);
}
}
//后序遍历
void postorder(TreeNode *p) {
if (p) {
postorder (p->lchild);
postorder (p->rchild);
cout<<p->data<<" ";
}
}
//计算叶子数
int CountLeaf(TreeNode *p) {
if(p==NULL)return 0;
else if(p->lchild==NULL&&p->rchild==NULL)
return CountLeaf(p->lchild)+CountLeaf(p->rchild)+1;
else return CountLeaf(p->lchild)+CountLeaf(p->rchild);
}
//计算二叉树树高
int CountHeight(TreeNode *p) {
int m(0),n(0);
if(p==NULL) return 0;
else {
m=CountHeight(p->lchild);
n=CountHeight(p->rchild);
if(m>n) return(m+1);
else return(n+1);
}
}
//左右子树交换
void Change(TreeNode *p) {
TreeNode *temp;
if(p) {
temp = new TreeNode;
temp = p->lchild;
p->lchild = p->rchild;
p->rchild = temp;
Change(p->lchild);
Change(p->rchild);
}
}
//二叉树拷贝
void Copy(TreeNode *T,TreeNode *&NewT) {
if(T==NULL) {
NewT=NULL;
return ;
} else {
NewT=new TreeNode;
NewT->data=T->data;
Copy(T->lchild,NewT->lchild);
Copy(T->rchild,NewT->rchild);
}
}
//二叉树拷贝
void CopyTh(TreeNode *T,Node *&NewT) {
if(T==NULL) {
NewT=NULL;
return ;
} else {
NewT=new Node;
NewT->data=T->data;
NewT->ltag = NewT->rtag = 0;
CopyTh(T->lchild,NewT->lchild);
CopyTh(T->rchild,NewT->rchild);
}
}
//非递归后序遍历
void postOrder(TreeNode *t) {
TreeNode* a[10];
TreeNode* p=t;
int i = 0;
while(i>=0) {
if(p!=NULL&&p->left==true&&p->right==true) {
cout << p->data << " ";
i--;
p = a[i];
} else if(p!=NULL&&p->left==true&&p->right==false) {
p->right = true;
p = p->rchild;
i++;
a[i] = p;
} else if(p!=NULL&&p->left==false&&p->right==false) {
p->left = true;
a[i] = p;
i++;
p = p->lchild;
} else if(p==NULL) {
if(a[i-1]->left==true&&a[i-1]->right==false) {
p = a[i-1];
p->right = true;
p = p->rchild;
} else {
i--;
p = a[i];
}
}
}
return;
}
void menu() {
cout << "请选择操作(选择对应序号):" << endl;
cout<<" 1.先序遍历二叉树"<<endl;
cout<<" 2.中序遍历二叉树"<<endl;
cout<<" 3.后序遍历二叉树"<<endl;
cout<<" 4.统计叶子数"<<endl;
cout<<" 5.计算树高"<<endl;
cout<<" 6.左右子树交换,输出交换后的前序、中序遍历序列(其他操作仍以原来树为基础)"<<endl;
cout<<" 7.非递归的后序遍历"<<endl;
cout<<" 8.扩充为中序线索树,写出非递归的中序遍历"<<endl;
cout<<" 9.在两个数组中分别有前序和中序遍历序列,建立该二叉树"<<endl;
cout<<" 0.退出"<<endl;
cout << endl;
}
//中序线索化
void InThreading(Node *p) {
if(p!=NULL) {
InThreading(p->lchild);
if(p->lchild==NULL) {
p->ltag=1;
p->lchild=pre;
}
if(pre->rchild==NULL) {
pre->rtag=1;
pre->rchild=p;
}
pre=p;
InThreading(p->rchild);
}
}
void InorderThread(Node *thrt,Node *t) {
thrt->ltag=0;
thrt->rtag=1;
thrt->rchild=thrt;
if(t==NULL) thrt->lchild=thrt;
else {
thrt->lchild=t;
pre=thrt;
InThreading(t);
pre->rchild=thrt;
pre->rtag=1;
thrt->rchild=pre;
}
}
//线索二叉树非递归中序遍历
void inOrder(Node *t) {
Node *p=t->lchild;
while(p!=t) {
while(p->ltag==0) p=p->lchild;
cout<<p->data<<" ";
while (p->rtag == 1 && p->rchild!=t) {
p=p->rchild;
cout<<p->data<<" ";
}
p=p->rchild;
}
}
//已知前序和中序遍历序列,建立该二叉树
TreeNode_ *RebuildTree_(int* startPrev,int* endPrev,int* startIn,int* endIn) {
int rootValue = startPrev[0];
TreeNode_* root = new TreeNode_;
root->value = rootValue;
root->lchild = NULL;
root->rchild = NULL;
if (startPrev == endPrev) {
return root;
}
int* rootIn = startIn;
while (rootIn <= endIn && *rootIn != rootValue) {
++rootIn;
}
int leftLength = rootIn - startIn;
int* leftPrevEnd = startPrev + leftLength;
if (leftLength > 0) {
root->lchild = RebuildTree_(startPrev + 1, leftPrevEnd, startIn, rootIn - 1);
}
if (leftLength < endPrev - startPrev) {
root->rchild = RebuildTree_(leftPrevEnd + 1, endPrev, rootIn + 1, endIn);
}
return root;
}
TreeNode_ *RebuildTree(int* prev, int* in, int len) {
if (prev == NULL || in == NULL || len <= 0) {
return NULL;
}
return RebuildTree_(prev, prev + len - 1, in, in + len + -1);
}
void PreOrder(TreeNode_ *root) {
if (root == NULL)
return;
cout << root->value << " ";
PreOrder(root->lchild);
PreOrder(root->rchild);
}
void PostOrder(TreeNode_ *root) {
if (root == NULL)
return;
PostOrder(root->lchild);
PostOrder(root->rchild);
cout << root->value << " ";
}
int main() {
TreeNode *root;
Node *th_root;
cout << "请先创建二叉树(以先序输入,*表示空):(eg:abd**e**cf**g**)" << endl;
CreateBiTree(root);
cout << "二叉树创建完成!" << endl<<endl;
int function = 0;
menu();
while(cin>>function) {
if(function==0)
break;
switch(function) {
case 1: {
cout << "先序遍历输出为:";
preorder(root);
cout << endl<<endl;
break;
}
case 2: {
cout << "中序遍历输出为:";
inorder(root);
cout << endl<<endl;
break;
}
case 3: {
cout << "后序遍历输出为:";
postorder(root);
cout << endl<<endl;
break;
}
case 4: {
cout << "叶子数为:";
int leaf_count=CountLeaf(root);
cout << leaf_count << endl;
cout << endl;
break;
}
case 5: {
cout << "树高为:";
int tree_height=CountHeight(root);
cout << tree_height << endl;
cout << endl;
break;
}
case 6: {
TreeNode *root_temp;
Copy(root, root_temp);
Change(root_temp);
cout << "左右子树交换后的序列为" << endl;
cout << "前序为:";
preorder(root_temp);
cout << endl;
cout << "后序为:";
postorder(root_temp);
cout << endl;
cout << endl;
break;
}
case 7: {
cout << "非递归后序遍历为:" << endl;
postOrder(root);
cout << endl;
cout << endl;
break;
}
case 8: {
//Node *temp = new Node;
cout << "线索化二叉树非递归中序遍历输出为:";
CopyTh(root, th_root);
Node *thrt = new Node;
InorderThread(thrt,th_root);
inOrder(thrt);
cout << endl;
cout << endl;
break;
}
case 9: {
int prev[7];
//= {1, 2, 3, 4, 5, 6, 7};
int in[7];
//= {3, 2, 4, 1, 6, 5, 7};
cout << "请输入先序序列(设定整型数组大小为7):(eg:1 2 3 4 5 6 7):";
for (int i = 0; i<7; i++)
cin >> prev[i];
cout << endl;
cout << "请输入中序序列(设定整型数组大小为7):(eg:3 2 4 1 6 5 7):";
for (int i = 0; i<7; i++)
cin >> in[i];
cout << endl;
TreeNode_ *re_root = RebuildTree(prev, in, 7);
cout << "已知先序和中序新建二叉树" << endl;
cout << "前序遍历:";
PreOrder(re_root);
cout << endl;
cout << "后序遍历:";
PostOrder(re_root);
cout << endl;
cout << endl;
break;
}
}
menu();
}
}
C++学习记录1~~~~~二叉树相关操作
于 2021-04-24 22:22:42 首次发布
这个程序实现了二叉树的各种操作,包括先序、中序、后序遍历,计算叶子数和树高,左右子树交换,以及通过先序和中序序列重建二叉树。此外,还提供了非递归的后序遍历和线索二叉树的中序遍历。用户可以交互选择不同的操作来观察二叉树的状态。
摘要由CSDN通过智能技术生成