二元树遍历与常见操作

 
#include <cstdio>
#include <cstdlib>
#include <stack>
#include <queue>
#include <list>
using namespace std;

struct btree{
	btree(char c):data(c),left(NULL),right(NULL){}
	char data;
	btree *left, *right;
};
void preOrder(btree* root){
	btree* ptr = root;
	stack<btree*> st;
	while(!st.empty() || ptr!=NULL){
		if(ptr!=NULL){
			printf("%c\t", ptr->data);
			st.push(ptr);
			ptr = ptr->left;
		}else{
			ptr = st.top()->right;
			st.pop();
		}
	}
}
void midOrder(btree* root){
	btree* ptr = root;
	stack<btree*> st;
	while(!st.empty() || ptr!=NULL){
		if(ptr!=NULL){
			st.push(ptr);
			ptr = ptr->left;
		}else{
			printf("%c\t", st.top()->data);
			ptr = st.top()->right;
			st.pop();
		}
	}
}
void postOrder(btree* root){
	btree* ptr = root;
	stack<btree*> st;
	stack<bool> sflag;
	while(!st.empty() || ptr!=NULL){
		if(ptr!=NULL){
			st.push(ptr), sflag.push(false);
			ptr = ptr->left;
		}else if(sflag.top()==false){
			ptr = st.top()->right;
			sflag.top() = true;
		}else{
			printf("%c\t", st.top()->data);
			st.pop(), sflag.pop();
		}
	}
}
void levelOrder(btree* root){
	queue<btree*> q;
	q.push(root);
	while(!q.empty()){
		btree* ptr = q.front();
		q.pop();
		printf("%c\t", ptr->data);
		if(ptr->left!=NULL)
			q.push(ptr->left);
		if(ptr->right!=NULL)
			q.push(ptr->right);
	}
}
void maxDis(btree* root, int& h, int& dis, list<char>& listh, list<char>& listd){
	int lh, rh, ld, rd;
	list<char> listlh, listrh, listld, listrd;
	if(root!=NULL){
		maxDis(root->left,lh,ld,listlh,listld);
		maxDis(root->right,rh,rd,listrh,listrd);
		h = max(lh,rh) + 1;
		listh = lh>=rh? listlh : listrh;//to dump path
		listh.push_back(root->data);//to dump path
		dis = max(max(ld,rd), rh+lh+2);
		/*to dump path*/
		if(ld >= rd && ld >= rh+lh+2)
			listd = listld;
		else if(rd >= ld && rd >= rh+lh+2)
			listd = listrd;
		else{
			listd = listlh;
			listd.push_back(root->data);
			for(list<char>::reverse_iterator it=listrh.rbegin();it!=listrh.rend();it++){
				listd.push_back(*it);
			}
		}
	}else{
		h = -1, dis = 0;
	}
}
void btreeMirror(btree* root)
{
	if(root!=NULL){
		btree* tmp = root->left;
		root->left = root->right;
		root->right = tmp;
		btreeMirror(root->left);
		btreeMirror(root->right);
	}
}
void btreeCopy(const btree* src, btree*& des)
{
	if(src==NULL){
		des = NULL;
	}else{
		des = new btree(src->data);
		btree *l, *r;
		btreeCopy(src->left, l);
		btreeCopy(src->right, r);
		des->left = l;
		des->right = r;
	}
}
bool btreeComp(const btree* src, btree* des)
{
	if(src==NULL && des!=NULL || src!=NULL && des==NULL)
		return false;
	else if(src==NULL && des==NULL)
		return true;
	else{
		if(src->data==des->data)
			return btreeComp(src->left,des->left) && btreeComp(src->right,des->right);
		else
			return false;
	}
}
typedef void(*FUNC)(btree* root);
int main()
{
	FUNC func[] = {preOrder, midOrder, postOrder, levelOrder};
	int funcSize = sizeof(func)/sizeof(FUNC);
	const char* funcName[] = {"preOrder", "midOrder", "postOrder", "levelOrder"};

	btree a('a'),b('b'),c('c'),d('d'),e('e'),f('f'),g('g');
	a.left = &b, a.right = &c;
	b.left = &d, b.right = &e;
	e.left = &f, e.right = &g;
	btree* root = &a;
	
	for(int i=0;i<funcSize;i++){
		printf("%s:\t", funcName[i]);
		(*func[i])(root);
		printf("\n");
	}
	btree *copy;
	btreeCopy(&a,copy);
	
	if(btreeComp(&a,copy)){
		printf("tree copy:\t");
		preOrder(copy);	
		printf("\n");
	}else{
		printf("something wrong!\n");
		exit(1);
	}
	btreeMirror(copy);
	printf("tree mirror:\t");
	preOrder(copy);
	printf("\n");

	int high, distance;
	list<char> lhigh, ldistance;
	maxDis(root,high, distance, lhigh, ldistance);
	printf("max distance:\t%d\npath:\t", distance);
	for(list<char>::iterator it=lhigh.begin();it!=lhigh.end();it++){
		printf("%c\t", *it);
	}
	printf("\n");
	printf("height:\t:%d\npath:\t", high);
	for(list<char>::iterator it=ldistance.begin();it!=ldistance.end();it++){
		printf("%c\t", *it);
	}
	printf("\n");

	return 0;	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值