二叉树算法一之创建和遍历

  按照数据结构的课本,栈和队列的下一章知识应该是串,但是c语言中对于字符串都是字符数组的概念,且基本的方法都已经封装了,对于c++来说,直接有string这种数据类型,唯一能讲的应该是KMP算法, 但是没有研究过,数组和广义表也用的很少,都跳过,所以这章将重点介绍二叉树,二叉树讲解讲覆盖二叉树的创建和遍历、线索二叉树、哈夫曼树等,二叉树这一章基本都是递归,对于我来说应该是个挑战,尽量专心研究吧。

   树这一节概念比较多,如果光介绍概念和各种不同的二叉树的性质都需要几页纸,但是有一个性质非常重要,就是对于任何一颗二叉树T,如果其终端结点数为n,度为2的结点树为m,则n=m+1(由于没法下标,书上带下标的公式更方便理解),树也是数据结构的常考题和笔试的基本题。

   1.有很多题都是这个公式的延伸,如阿里笔试的第12题,原题如下:在一棵度为4的树T中,若有20个度为4的结点,10个度为3的结点,1个度为2的结点,10个度为1的结点,则树T的叶子结点有多少个?

树的度数之和+1=树的总结点数:20*4+10*3+1*2+10*1+n*0+1=20+10+1+10+n    =>n=82

   2.还有一种题,就是求n个结点的不同形态的二叉树的数目,例如最简单的n=3,当然你可以自己一个一个枚举,但是有数学公式就是1/(n+1)*C(2n,n),可求得答案是1/4*C(6,3)=5,是不是感觉似曾相识,bingo,在介绍n个元素的出栈顺序时也使用的这个,其实都是卡特兰数,具体的可以参看数据结构课本P155页(绿皮书那个),就是图那一章的前一页

   3.对于就是求二叉树的的前序(根左右)、中序(左根右)、后序(左右根)遍历也是常见的题目,还有什么已知前序和中序求后序,但是需要记住的是已知前序和后序,不能求出唯一的二叉树,更不用说求中序了

   

   二叉树也有顺序储存结构和链式存储结构,但是大部分的程序都是使用链式存储结构。二叉树链式的存储结构是

struct BiTree{
	struct BiTree *lchild,*rchild;
	char data;
};
   二叉树的代码这块基本都是递归,方便理解,但是递归本身不好理解,多加上断点看看,然后递归的过程需要看成栈的模拟过程,创建二叉树的代码如下:

struct BiTree* createTree(){
	char ch;
	scanf("%c",&ch);    //实际输入是一个字符串,书上的例子是ABC##DE#G##F###,让scanf自动读入洗一个字符
	struct BiTree *root;
	if(ch=='#')  root=NULL;
	else{
		if(!(root=(struct BiTree*)malloc(sizeof(struct BiTree))))  return NULL;
		root->data=ch;
		root->lchild=createTree();
		root->rchild=createTree();
	}
	return root;
}
先序、中序和后序的代码基本都一样,也是递归,理解了一个也就是三个了

void preOrder(struct BiTree *root){
	if(root==NULL) return;
	printf("%c",root->data);
	preOrder(root->lchild);
	preOrder(root->rchild);
}

void inOrder(struct BiTree *root){
	if(root==NULL) return;
	inOrder(root->lchild);
	printf("%c",root->data);
	inOrder(root->rchild);
}

void postOrder(struct BiTree *root){
	if(root==NULL) return;
	postOrder(root->lchild);
	postOrder(root->rchild);
	printf("%c",root->data);
}

   但是书还有另外一种遍历,就是层次遍历,但是需要借助数据结构队列的知识,例如一个节点为8个的完全二叉树,按找英文字母顺序表示这8个结点,遍历的过程是:先把A入队,然后A的左右结点BC入队,然后A出对,然后B的左右结点入队,B出对,然后C入队……(shift+^=省略号)

代码如下:

void levelOrder(struct BiTree *root){
	queue<struct BiTree *>q;
	q.push(root);
	while(!q.empty()){
		if(q.front()->lchild!=NULL)  q.push(q.front()->lchild);
		if(q.front()->rchild!=NULL)  q.push(q.front()->rchild);
		printf("%c",q.front()->data);
		q.pop();
	}
}
总的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <queue>
using namespace std;

#define MAXN 80

struct BiTree{
	struct BiTree *lchild,*rchild;
	char data;
};

struct BiTree* createTree(){
	char ch;
	scanf("%c",&ch);
	struct BiTree *root;
	if(ch=='#')  root=NULL;
	else{
		if(!(root=(struct BiTree*)malloc(sizeof(struct BiTree))))  return NULL;
		root->data=ch;
		root->lchild=createTree();
		root->rchild=createTree();
	}
	return root;
}

void preOrder(struct BiTree *root){
	if(root==NULL) return;
	printf("%c",root->data);
	preOrder(root->lchild);
	preOrder(root->rchild);
}

void inOrder(struct BiTree *root){
	if(root==NULL) return;
	inOrder(root->lchild);
	printf("%c",root->data);
	inOrder(root->rchild);
}

void postOrder(struct BiTree *root){
	if(root==NULL) return;
	postOrder(root->lchild);
	postOrder(root->rchild);
	printf("%c",root->data);
}

void levelOrder(struct BiTree *root){
	queue<struct BiTree *>q;
	q.push(root);
	while(!q.empty()){
		if(q.front()->lchild!=NULL)  q.push(q.front()->lchild);
		if(q.front()->rchild!=NULL)  q.push(q.front()->rchild);
		printf("%c",q.front()->data);
		q.pop();
	}
}

int main(){
	char str[MAXN];
	struct BiTree *root=createTree();

	preOrder(root);
	printf("\n");

	inOrder(root);
	printf("\n");

	postOrder(root);
	printf("\n");

	levelOrder(root);
	printf("\n");
	return 0;
}


未完待续 下一节 二叉树算法二之中序线索

如果文章有什么错误或者有什么建议,欢迎提出,大家共同交流,一起进步

文章转载请注明出处,请尊重知识产权

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值