二叉树·专题一
一、章鱼浅谈二叉树与其建立
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;
}
二、章鱼挖一挖二叉树的遍历
二叉树,三种遍历方式即前、中、后序遍历
- 前序遍历:先访问根结点,再访问左子树,再访问右子树
- 中序遍历:先访问左子树,再访问根结点,再访问右子树
- 后序遍历:先访问左子树,再访问右子树,再访问根结点 **访问就是要输出来**
在建立过程中章鱼提示大家要注意,访问根就是先访问每一个形参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~