二叉树的基本操作

二叉树作为一种非常重要的数据结构,今天对其做简单的回顾
1、二叉树的定义

typedef char ElementType;

typedef struct BiTreeNode
{
	ElementType data;
    struct BiTreeNode* lchild;
    struct BiTreeNode* rchild;
}BiTreeNode, *BiTree;
2、 二叉树的建立和销毁

(1)利用先序序列递归建立二叉树

//递归的建立一棵二叉树 
//输入为二叉树的先序序列 
void createBiTree(BiTree &T)
{
	char data;
	data = getchar();
	if(data == '#')
	{
		T = NULL;
	}
	else
	{
		T = new BiTreeNode;
		T->data = data;
		createBiTree(T->lchild);
		createBiTree(T->rchild);
	}
}

(2)利用广义表建立二叉树

//通过广义表建立二叉树 
void createBiTreeWithGenList(BiTree &T)
{
	stack<BiTree> s;//存放待输入孩子的结点 
	BiTree p = NULL;//用于生成新的结点
	int k = 0;//记录期待的结点, k==1表示期待左孩子结点,k==2期待右孩子结点
	char ch = getchar();
	
	//处理根结点 
	if(ch!='#')
	{
		p = new BiTreeNode;
		p->data = ch;
		p->lchild = NULL;
		p->rchild = NULL;
		T = p;//根结点 
	}
	while((ch=getchar())!='#')
	{
		switch(ch)
		{
			case '(':
				s.push(p);//上一个生成的结点,即p入栈,p有孩子 
				k = 1;	//下一个插入的应为左孩子结点 
				break;
			case ',':
				k = 2;	//下一个插入的应为右孩子结点 
				break;
			case ')':
				s.pop();//结点完成孩子的输入,出栈 
				break;
			default:
				p = new BiTreeNode;
				p->data = ch;
				p->lchild = NULL;
				p->rchild = NULL;
				if(k==1)
					s.top()->lchild = p;
				else 
					s.top()->rchild = p;
		}		
	}
}

(3)输出二叉树的广义表表示

//以广义表的方式输出二叉树
void printBiTreeWithGenList(const BiTree&T)
{
	if(T)
	{
		cout<<T->data;
		if(T->lchild ||T->rchild)//左右子树不全空 
		{
			cout<<"(";
			printBiTreeWithGenList(T->lchild);//递归输出左子树 ,可能为空 
			if(T->rchild)		
			{
				cout<<",";
				printBiTreeWithGenList(T->rchild);
			}
			cout<<")";
		}
	}
}

(4)二叉树的销毁

//递归销毁一棵二叉树
void destroyBiTree(BiTree &T)
{
	if(T)
	{
		destroyBiTree(T->lchild);
		destroyBiTree(T->rchild);
		delete T;
		T = NULL;
	}
}
3 、二叉树的递归遍历

(1)先序递归遍历

//递归先序遍历二叉树 
void preOrderTraverse(const BiTree &T)
{
	if(T)
	{
		cout<<T->data<<" ";//输出根节点值 
		preOrderTraverse(T->lchild);//遍历左子树 
		preOrderTraverse(T->rchild);//遍历右子树 
	}
}

(2)中序递归遍历

//递归中序遍历二叉树
void inOrderTraverse(const BiTree &T)
{
	if(T)
	{
		inOrderTraverse(T->lchild);//遍历左子树 
		cout<<T->data<<" ";//输出根节点值 
		inOrderTraverse(T->rchild);//遍历右子树 
	}
}

(3)后序递归遍历

//递归后序遍历二叉树
void postOrderTraverse(const BiTree &T)
{
	if(T)
	{
		postOrderTraverse(T->lchild);//遍历左子树 
		postOrderTraverse(T->rchild);//遍历右子树 
		cout<<T->data<<" ";//输出根节点值 
	} 
}

4 、二叉树的其他常见递归算法

(1)递归求树的深度(高度)

//递归求树的深度 
int depthOfBiTree(const BiTree &T)
{
	int ldepth;
	int rdepth;
	
	if(T==NULL)//空树 
		return 0;
	ldepth = depthOfBiTree(T->lchild);
	rdepth = depthOfBiTree(T->rchild);
	
	return (ldepth>rdepth)?(ldepth+1):(rdepth+1);
}

(2)递归求树的叶子结点个数

//递归求二叉树的叶子结点个数
int leafCountOfBiTree(const BiTree &T)
{	
	if(T==NULL)
		return 0;
	if(T->lchild==NULL && T->rchild==NULL)
		return 1;
	return leafCountOfBiTree(T->lchild) + leafCountOfBiTree(T->rchild);
}
(3)递归交换左右子女
//交换二叉树的左右子女
void exchangeChild(BiTree &T)
{
	if(T)
	{
		BiTree temp = NULL;
		
		if(T->lchild ||T->rchild)
		{
			temp = T->lchild;
			T->lchild = T->rchild;
			T->rchild = temp;
			exchangeChild(T->lchild);
			exchangeChild(T->rchild);
		}
	}
}

5、完整的测试代码

#include <cstdlib>
#include <iostream>
#include <stack>

using namespace std;

//二叉树定义 
typedef char ElementType;

typedef struct BiTreeNode
{
	ElementType data;
    struct BiTreeNode* lchild;
    struct BiTreeNode* rchild;
}BiTreeNode, *BiTree;


//递归的建立一棵二叉树 
//输入为二叉树的先序序列 
void createBiTree(BiTree &T)
{
	char data;
	data = getchar();
	if(data == '#')
	{
		T = NULL;
	}
	else
	{
		T = new BiTreeNode;
		T->data = data;
		createBiTree(T->lchild);
		createBiTree(T->rchild);
	}
}

//通过广义表建立二叉树 
void createBiTreeWithGenList(BiTree &T)
{
	stack<BiTree> s;//存放待输入孩子的结点 
	BiTree p = NULL;//用于生成新的结点
	int k = 0;//记录期待的结点, k==1表示期待左孩子结点,k==2期待右孩子结点
	char ch = getchar();
	
	//处理根结点 
	if(ch!='#')
	{
		p = new BiTreeNode;
		p->data = ch;
		p->lchild = NULL;
		p->rchild = NULL;
		T = p;//根结点 
	}
	while((ch=getchar())!='#')
	{
		switch(ch)
		{
			case '(':
				s.push(p);//上一个生成的结点,即p入栈,p有孩子 
				k = 1;	//下一个插入的应为左孩子结点 
				break;
			case ',':
				k = 2;	//下一个插入的应为右孩子结点 
				break;
			case ')':
				s.pop();//结点完成孩子的输入,出栈 
				break;
			default:
				p = new BiTreeNode;
				p->data = ch;
				p->lchild = NULL;
				p->rchild = NULL;
				if(k==1)
					s.top()->lchild = p;
				else 
					s.top()->rchild = p;
		}		
	}
}

//以广义表的方式输出二叉树
void printBiTreeWithGenList(const BiTree&T)
{
	if(T)
	{
		cout<<T->data;
		if(T->lchild ||T->rchild)//左右子树不全空 
		{
			cout<<"(";
			printBiTreeWithGenList(T->lchild);//递归输出左子树 ,可能为空 
			if(T->rchild)		
			{
				cout<<",";
				printBiTreeWithGenList(T->rchild);
			}
			cout<<")";
		}
	}
}
 
//递归销毁一棵二叉树
void destroyBiTree(BiTree &T)
{
	if(T)
	{
		destroyBiTree(T->lchild);
		destroyBiTree(T->rchild);
		delete T;
		T = NULL;
	}
} 

//递归先序遍历二叉树 
void preOrderTraverse(const BiTree &T)
{
	if(T)
	{
		cout<<T->data<<" ";//输出根节点值 
		preOrderTraverse(T->lchild);//遍历左子树 
		preOrderTraverse(T->rchild);//遍历右子树 
	}
}

//递归中序遍历二叉树
void inOrderTraverse(const BiTree &T)
{
	if(T)
	{
		inOrderTraverse(T->lchild);//遍历左子树 
		cout<<T->data<<" ";//输出根节点值 
		inOrderTraverse(T->rchild);//遍历右子树 
	}
}

//递归后序遍历二叉树
void postOrderTraverse(const BiTree &T)
{
	if(T)
	{
		postOrderTraverse(T->lchild);//遍历左子树 
		postOrderTraverse(T->rchild);//遍历右子树 
		cout<<T->data<<" ";//输出根节点值 
	} 
}

//递归求树的深度 
int depthOfBiTree(const BiTree &T)
{
	int ldepth;
	int rdepth;
	
	if(T==NULL)//空树 
		return 0;
	ldepth = depthOfBiTree(T->lchild);
	rdepth = depthOfBiTree(T->rchild);
	
	return (ldepth>rdepth)?(ldepth+1):(rdepth+1);
}

//递归求二叉树的叶子结点个数
int leafCountOfBiTree(const BiTree &T)
{	
	if(T==NULL)
		return 0;
	if(T->lchild==NULL && T->rchild==NULL)
		return 1;
	return leafCountOfBiTree(T->lchild) + leafCountOfBiTree(T->rchild);
} 

//递归交换二叉树的左右子女
void exchangeChild(BiTree &T)
{
	if(T)
	{
		BiTree temp = NULL;
		
		if(T->lchild ||T->rchild)
		{
			temp = T->lchild;
			T->lchild = T->rchild;
			T->rchild = temp;
			exchangeChild(T->lchild);
			exchangeChild(T->rchild);
		}
	}
}
 
int main(int argc, char *argv[])
{
	BiTree T = NULL;
	
	createBiTree(T);//建立二叉树 如输入AB#D##CE### 
//	createBiTreeWithGenList(T);//如输入A(B(,D),C(E))#
	
	cout<<"preOrder: "; //先序遍历 
	preOrderTraverse(T);
	cout<<endl;
	
	cout<<"inOrder: ";//中序遍历 
	inOrderTraverse(T);
	cout<<endl;
	
	cout<<"postOrder: ";//后序遍历 
	postOrderTraverse(T);
	cout<<endl;
	
	cout<<"depth: "<<depthOfBiTree(T)<<endl;//树的高度 
	
	cout<<"the count of leaf: "<<leafCountOfBiTree(T)<<endl;//叶子结点数 
	
	cout<<"The tree after exchange: ";
	exchangeChild(T);
	printBiTreeWithGenList(T);
	
	destroyBiTree(T);//销毁二叉树,释放空间 
	
    system("PAUSE");
    return EXIT_SUCCESS;
}
注:二叉树的非递归遍历及层次遍历,请看 http://blog.csdn.net/sysu_arui/article/details/7865873




  • 13
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
二叉树是一种非常重要的数据结构,它的基本操作包括创建、销毁、遍历、查找等。下面是二叉树基本操作的实现方法: 1. 创建二叉树:通过前序遍历的数组构建二叉树,其中 '#' 表示空节点。具体实现方法可以参考引用中的 BinaryTreeCreate 函数。 2. 销毁二叉树:遍历二叉树,依次释放每个节点的内存空间。具体实现方法可以参考引用中的 BinaryTreeDestory 函数。 3. 遍历二叉树二叉树的遍历包括前序遍历、中序遍历、后序遍历和层序遍历。具体实现方法可以参考引用中的 BinaryTreePrevOrder、BinaryTreeInOrder、BinaryTreePostOrder 和 BinaryTreeLevelOrder 函数。 4. 查找二叉树节点:在二叉树中查找值为 x 的节点,具体实现方法可以参考引用中的 BinaryTreeFind 函数。 5. 计算二叉树节点个数:计算二叉树中节点的个数,具体实现方法可以参考引用[2]中的 BinaryTreeSize 函数。 6. 计算二叉树叶子节点个数:计算二叉树中叶子节点的个数,具体实现方法可以参考引用中的 BinaryTreeLeafSize 函数。 7. 计算二叉树第 k 层节点个数:计算二叉树中第 k 层节点的个数,具体实现方法可以参考引用中的 BinaryTreeLevelKSize 函数。 8. 判断二叉树是否是完全二叉树:判断二叉树是否是完全二叉树,具体实现方法可以参考引用中的 BinaryTreeComplete 函数。 9. 计算二叉树的深度:计算二叉树的深度,具体实现方法可以参考引用中的 BinaryTreeDeep 函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值