C++学习记录1~~~~~二叉树相关操作

这个程序实现了二叉树的各种操作,包括先序、中序、后序遍历,计算叶子数和树高,左右子树交换,以及通过先序和中序序列重建二叉树。此外,还提供了非递归的后序遍历和线索二叉树的中序遍历。用户可以交互选择不同的操作来观察二叉树的状态。
摘要由CSDN通过智能技术生成
#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();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值