二叉树·专题1——建立和遍历

本文由海底大章鱼讲解二叉树的概念、建立规则和三种遍历方式。二叉树定义为每个节点最多有两个子节点,创建时遵循新节点小于父节点放左子树,大于放右子树的原则。遍历方式包括前序、中序和后序,分别对应不同的访问顺序。章鱼提供了详细的操作示例和代码实现。
摘要由CSDN通过智能技术生成

二叉树·专题一

一、章鱼浅谈二叉树与其建立  

  HEELO!大家好,我是海底大章鱼,没时间扯淡了,来畅游程序大海!

 二叉树这个神奇的树是一棵什么样的树呢,其实就是一个带了两个指针的链表,在内存里又不可能看到这么大个树状对不对啊,所以啊没必要过分紧张,想要学好二叉树的同学们可以放纵放纵。。。。。。咳咳,放松放松,放松放松啦!

来!大章鱼带你们挖一挖程序员海底下面的细节!二叉树的定义:最大度值为2。

                                                           通俗点,就是每一个结点必须有两个分支!

                                                                                                                                                                                           但每一个分支不一定有值!


  二叉树就是带着两个指针域的链表塞!平时我们的链表是怎么说的呢,下面一小段程序告诉你答案:

typedef struct node{
	int data;
	struct node *next;
}ElemSN;

画个图来参照一下:


好!接下来我们来看看二叉树这个叫树非树的东西是个什么鬼,带两个指针又是个什么锤子的结点,再来一段小程序:

typedef struct node{
	int data;
	struct node *left;
	struct node *right;
}BTNode;

再来画个图参照一下:


看! 看!看~~!

就是上面这个东西构成了二叉树的结点!然后left边引出一颗左子树,right边引出一颗右子树,两个树一起构成的就是二叉树!

好啦,接下来我们来讨论一下二叉树的结点是如何接起来(怎么创建起来)!

建立前,本章鱼在这里规定,

1、当新结点大小比父结点小时,要放在左子树

2、当新结点比父结点小的时候,要放在右子树!

创建的过程就是递归的过程,执行的过程参见海底大章鱼博客的《链表的递归建立与输出》点击打开链接一节。

不过在二叉树的递归建立过程中呢,我们要注意的是:

while(c){    //当c不为空的时候
	pa=c;
	if(c->data>p->data)
		c=c->left;
        else
		c=c->right;
}	
if(pa->data>p->data)
	pa->left=p;
else
	pa->right=p;

这个循环条件中,c->data>p->data必须于pa->data>p->data时执行的语句一样

即当执行第一个if(c->data>p->data)语句时,运行结果为c=c->left,

则在执行if(pa->data>p->data)语句时,运行结果为pa->left=p;

也就是说判定大小的时候,left与left对应,right与right对应!

章鱼的函数就这么写出来了

BTNode *CreatBTree(int a[],int n)
{
	BTNode *root,*c,*pa,*p;
	int i;
	root=(BTNode *)malloc(sizeof(BTNode));
	root->data=a[0];  //创建根结点
	root->left=root->right=NULL;
	for(i=1;i<n;i++)
	{
		p=(BTNode *)malloc(sizeof(BTNode));
		p->data=a[i];
		p->left=p->right=NULL;
		c=root;      //准备一个指针c遍历二叉树
		while(c){    //当c不为空的时候
			pa=c;
			if(c->data>p->data)
				c=c->left;
		    else
				c=c->right;
		}	
		if(pa->data>p->data)
			pa->left=p;
		else
			pa->right=p;
	}
	return root;
}

二、章鱼挖一挖二叉树的遍历

  二叉树,三种遍历方式即前、中、后序遍历

  1. 前序遍历:先访问根结点,再访问左子树,再访问右子树
  2. 中序遍历:先访问左子树,再访问根结点,再访问右子树
  3. 后序遍历:先访问左子树,再访问右子树,再访问根结点           **访问就是要输出来**

 在建立过程中章鱼提示大家要注意,访问根就是先访问每一个形参root,然后是root->left,最后是root->right

                                                    访问左子树就是先访问每一个形参root->left,然后是root,最后是root->right

                                                    访问右子树就是先访问每一个形参root->left,然后是root->right,最后是root。

递归输出每一次都要建立一个形参,然后返回上一层,形参释放。详情请参见海底大章鱼博客的《链表的递归建立与输出》点击打开链接一节。

那么三中遍历就是三条语句互换位置的过程了啦,不多解释,直接锤代码!

  • 序遍历
void Forder(BTNode *root)
{
	if(root)
	{
		printf("%5d",root->data);
		Forder(root->left);
		Forder(root->right);
	}
}
  • 序遍历
void Inorder(BTNode *root)
{
	if(root)
	{
		Inorder(root->left);
		printf("%5d",root->data);
		Inorder(root->right);
	}
}
  • 序遍历
void Porder(BTNode *root)
{
	if(root)
	{
		Inorder(root->left);
		Inorder(root->right);
		printf("%5d",root->data);
	}
}

三、总代码和实现

最后附上章鱼亲爪敲出的代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct node{
	int data;
	struct node *left;
	struct node *right;
}BTNode;

BTNode *CreatBTree(int a[],int n)
{
	BTNode *root,*c,*pa,*p;
	int i;
	root=(BTNode *)malloc(sizeof(BTNode));
	root->data=a[0];  //创建根结点
	root->left=root->right=NULL;
	for(i=1;i<n;i++)
	{
		p=(BTNode *)malloc(sizeof(BTNode));
		p->data=a[i];
		p->left=p->right=NULL;
		c=root;      //准备一个指针c遍历二叉树
		while(c){    //当c不为空的时候
			pa=c;
			if(c->data>p->data)
				c=c->left;
		    else
				c=c->right;
		}	
		if(pa->data>p->data)
			pa->left=p;
		else
			pa->right=p;
	}
	return root;
}

//前序遍历
void Forder(BTNode *root)
{
	if(root)
	{
		printf("%5d",root->data);
		Forder(root->left);
		Forder(root->right);
	}
}

//中序遍历
void Inorder(BTNode *root)
{
	if(root)
	{
		Inorder(root->left);
		printf("%5d",root->data);
		Inorder(root->right);
	}
}

//后序遍历
void Porder(BTNode *root)
{
	if(root)
	{
		Inorder(root->left);
		Inorder(root->right);
		printf("%5d",root->data);
	}
}

int main(void)
{
	BTNode *root;
	int a[9]={6,3,2,7,4,8,5,9,11};
	root=CreatBTree(a,9);
	printf("前序遍历:");
	Forder(root);
	printf("\n");
	printf("中序遍历:");
	Inorder(root);
	printf("\n");
	printf("后序遍历:");
	Porder(root);
	printf("\n");
}

结果是这样的哦:


  好啦,以上就是章鱼的二叉树浅谈!Bye~


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值