算法导论-第10章-10.4 二叉树之基础篇

一、二叉树的基本操作

1、二叉树的定义

<span style="font-size:10px;">typedef char ElementType;

typedef struct BiTreeNode
{
	ElementType data;
    struct BiTreeNode* lchild;
    struct BiTreeNode* rchild;
}BiTreeNode, *BiTree;</span><span style="font-size: 18px;">
</span>
2、 二叉树的建立和销毁
(1)利用先序序列递归建立二叉树

<span style="font-size:10px;">//递归的建立一棵二叉树 
//输入为二叉树的先序序列 
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);
	}
}</span><span style="font-size: 14px;">
</span>

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

<span style="font-size:10px;">//通过广义表建立二叉树 
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;
		}		
	}
}
</span>
(3)输出二叉树的广义表表示

<span style="font-size:10px;">//以广义表的方式输出二叉树
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<<")";
		}
	}
}
</span>
(4)二叉树的销毁

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

3 、二叉树的递归遍历

(1)先序递归遍历

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

(2)中序递归遍历

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

(3)后序递归遍历

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

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)递归求树的叶子结点个数

<span style="font-size:10px;">//递归求二叉树的叶子结点个数
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);
}</span><span style="font-size: 14px;">
</span>
(3)递归交换左右子女

<span style="font-size:10px;">//交换二叉树的左右子女
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);
		}
	}
}</span>
5、完整的测试代码

<span style="font-size:10px;">#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;
}
</span>


转自:http://blog.csdn.net/sysu_arui/article/details/7865876

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的公寓报修管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本公寓报修管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此公寓报修管理系统利用当下成熟完善的Spring Boot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的MySQL数据库进行程序开发。公寓报修管理系统有管理员,住户,维修人员。管理员可以管理住户信息和维修人员信息,可以审核维修人员的请假信息,住户可以申请维修,可以对维修结果评价,维修人员负责住户提交的维修信息,也可以请假。公寓报修管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:公寓报修管理系统;Spring Boot框架;MySQL;自动化;VUE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值