二叉树基本操作

#include <iostream>
#include <stdio.h>
#include<stack>
using namespace std;


//输入 "abdh..i..ej...cf..g.."

typedef struct Node
{
	char data;
	struct Node *left;
	struct Node *right;
}*pNode;

//建立二叉树
void create_tree(pNode &pRoot)
{
	char ch;
	scanf("%c",&ch);
	if(ch=='.')
	{
		pRoot = NULL;
	}
	else
	{
		pRoot = new Node();
		pRoot->left = NULL;
		pRoot->right = NULL;
		
		if(!pRoot)
			return ;
			
		pRoot->data = ch;//给T赋值
		create_tree(pRoot->left);//给左子树赋值
		create_tree(pRoot->right);//给右子树赋值
	}
}


void pre_show(Node *pRoot)//递归前序遍历二叉树
{
	if(pRoot)
	{
		std::cout<<pRoot->data<<" ";
		pre_show(pRoot->left);
		pre_show(pRoot->right);
	}
}

void pre_show_ex(Node* pRoot)//非递归前序遍历
{
	std::stack<Node*> ve;
	pNode tmp = pRoot;
	while(tmp || !ve.empty())
	{
		while(tmp)//显示当前节点信息,遍历该节点左子树
		{
			std::cout<<tmp->data<<" ";
			ve.push(tmp);
			tmp = tmp->left;
		}
		
		if(!ve.empty())//回退当前节点到右子树
		{
			tmp = ve.top();
			ve.pop();
			tmp = tmp->right;
		}
	}
}

void mid_show(Node *pRoot)//中序遍历二叉树
{
	if(pRoot)
	{
		mid_show(pRoot->left);
		std::cout<<pRoot->data<<" ";
		mid_show(pRoot->right);
	}
}

void mid_show_ex(Node* pRoot)//非递归中序遍历
{
	std::stack<Node*> ve;
	pNode tmp = pRoot;
	while(tmp || !ve.empty())
	{
		while(tmp)//遍历该节点左子树
		{
			ve.push(tmp);
			tmp = tmp->left;
		}
		
		if(!ve.empty())//显示当前节点信息,回退当前节点到右子树
		{
            tmp = ve.top();
			ve.pop();
			std::cout<<tmp->data<<" ";
			tmp = tmp->right;
		}
	}
}

void back_show(Node *pRoot)//后序遍历二叉树
{
	if(pRoot)
	{
		back_show(pRoot->left);
		back_show(pRoot->right);
		std::cout<<pRoot->data<<" ";
	}
}

void back_show_ex(Node* pRoot)//非递归后序遍历
{
	std::stack<Node*> ve;
	pNode tmp = pRoot;
	pNode flag = NULL;
	while(tmp || !ve.empty())
	{
		while(tmp)//遍历该节点左子树入栈
		{
			ve.push(tmp);
			tmp = tmp->left;
		}
		
		if(!ve.empty())
		{
            tmp = ve.top();
			if(tmp->right == NULL || flag == tmp->right)//如果没有右子树,或已经被访问过,则输出当前节点,并出栈
			{
				std::cout<<tmp->data<<" ";
				flag = tmp;
				tmp = NULL;
				ve.pop();
			}
			else//否则指向右子树
				tmp = tmp->right;
		}
	}
}

//层次遍历
void level_show(Node* pRoot)
{
	if(pRoot == NULL) 
		return; 
	std::deque<Node*> q; 
	q.push_back(pRoot); 
	while(!q.empty()) 
	{ 
		Node *pTmpNode = q.front(); 
		std::cout<<pTmpNode->data<<" "; 
		q.pop_front(); 
		if(pTmpNode->left != NULL) 
		{  
			q.push_back(pTmpNode->left); 
		} 
		if(pTmpNode->right != NULL) 
		{ 
			q.push_back(pTmpNode->right);  
		}  
	}
}

//获取叶子节点个数
int get_leaf_cnt(Node* pRoot)
{
	if(NULL == pRoot)
		return 0x00;
	
	if(pRoot->left == NULL && NULL == pRoot->right)
		return 0x01;
	
	return get_leaf_cnt(pRoot->left) + get_leaf_cnt(pRoot->right);
}

int get_leaf_cnt_ex(Node* pRoot)
{
	int cnt = 0x00;
	std::stack<Node*> ve;
	while(pRoot || !ve.empty())
	{
		if(pRoot)
		{
			ve.push(pRoot);
			if(pRoot->left == NULL && NULL == pRoot->right)
				cnt++;
			pRoot = pRoot->left;
		}
		else
		{
			pRoot = ve.top()->right;
			ve.pop();
		}
	}
	
	return cnt;
}

//获取二叉树高度
int get_tree_height(Node* pRoot)
{
	if(NULL == pRoot)
		return 0x00;
		
	int lh = get_leaf_cnt(pRoot->left);
    int rh = get_leaf_cnt(pRoot->right);
	
	return (lh > rh ? lh : rh) + 0X01;
}

//左右子树交换
void swap_node(Node* pRoot)
{
	if(pRoot)
	{
		Node* lf = pRoot->left;
		Node* rf = pRoot->right;
		pRoot->right = lf;
		pRoot->left = rf;
		
		swap_node(pRoot->left);
		swap_node(pRoot->right);
	}
}

//非递归交换左右子树
void swap_node_ex(Node* pRoot)
{
	Node* temp;
	std::stack<Node*> ve;
	while(pRoot || !ve.empty())
	{
		if(pRoot)
		{
			//当前节点入栈
			ve.push(pRoot);
			
			//交换当前节点的左右子树,并把左子树设置为当前节点
			temp = pRoot->left;
			pRoot->left = pRoot->right;
			pRoot->right = temp;
			pRoot = pRoot->left;
		}
		else
		{
			//出栈,获取节点的右子树为当前节点,继续遍历交换
			//遍历到这里说明上个节点的左子树已经遍历完毕,回退的话,需要遍历右子树了
			pRoot = ve.top()->right;
			ve.pop();
		}
	}
}

int main()
{
	Node *pRoot;
	std::cout<<"输入一串字符,子树为空,用.来代替"<<std::endl;
	
	create_tree(pRoot);
	std::cout<<"make btree ok"<<std::endl;

	std::cout<<"pre oreder result :";
	pre_show(pRoot);
	
	std::cout<<std::endl<<"pre oreder result--ex :";
	pre_show_ex(pRoot);
	
	std::cout<<std::endl<<"mid oreder result :";
	mid_show(pRoot);
	std::cout<<std::endl<<"mid oreder result-ex :";
	mid_show_ex(pRoot);

	std::cout<<std::endl<<"back oreder result :";
	back_show(pRoot);
	
	std::cout<<std::endl<<"back oreder result——ex :";
	back_show_ex(pRoot);
	
	std::cout<<std::endl<<"level show ---"<<std::endl;
	level_show(pRoot);
	std::cout<<std::endl;
	
	std::cout<<"sum_leaf_cnt:"<<get_leaf_cnt(pRoot)<<" ,ex:"<<get_leaf_cnt_ex(pRoot)<<std::endl;
	std::cout<<"height:"<<get_tree_height(pRoot)<<std::endl;
	
	//swap_node(pRoot);
	swap_node_ex(pRoot);
	std::cout<<"pre oreder result :";
	pre_show(pRoot);
	std::cout<<std::endl;
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值