Romi-知行合一

轻轻的风轻轻的梦,轻轻的晨晨昏昏, 淡淡的云淡淡的泪,淡淡的年年岁岁。
  博客园  :: 首页  :: 新随笔  :: 订阅 订阅  :: 管理

数据结构学习6——二叉树的构造

Posted on 2012-08-30 11:51  romi  阅读(16214)  评论(0编辑  收藏  举报

树是一种非线性的数据结构,树有根节点,子树等概念。

二叉树(Binary Tree):每个节点最多有两颗子树,并且子树有左右之分。

概念:树的深度,满二叉树,完全二叉树,树的节点树

二叉树包括顺序存储和链式存储,这里只说链式存储。二叉树的每个节点和双链表有些类似,但是树的结构要比双链表复杂,在构造树的过程中涉及到递归调用的问题,递归的问题往往是很复杂的问题,因此,这里单独说二叉树的构建。

国际惯例,先上代码:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<malloc.h>
 4 
 5 //定义二叉树
 6 typedef struct node{
 7     int data;//数据元素
 8     struct node *left;//指向左子树
 9     struct node *right;//指向右子树
10 }BTree;
11 
12 //构造二叉树
13 int BTreeCreate(BTree **tp)
14 {
15     //构造方法,或者说构造顺序:从左子树开始构造
16     int x;
17     scanf("%d",&x);
18     if(x<0)
19     {
20         *tp=NULL;//指针为空,树节点中的某个指针为空
21         return 0;
22     }
23     *tp=(BTree*)malloc(sizeof(BTree));//将树节点中指针指向该地址空间
24     if(tp==NULL)
25         return 0;
26     (*tp)->data=x;
27     BTreeCreate(&((*tp)->left));
28     BTreeCreate(&((*tp)->right));
29     return 1;
30 }
31 
32 int main()
33 {
34     BTree *tree;
35     printf("Create binary tree:\n");
36     BTreeCreate(&tree);
37 
38     return 0;
39 }

代码看似比较简单,核心就是BTreeCreate函数,该函数完成二叉树的构建,根据函数定义,只有输入正整数时才会新建节点。

二叉树的构建过程如下:

先创建某一子树的左子树,如果左子树不存在(输入负数时),则创建其右子树,如果左子树存在,再创建该树的左子树,依次循环。需要注意的是,当某一子树左子树不存在则判断其右子树,右子树不存在则返回其父节点再判断右子树。

特别要注意的是,一旦一个节点创建成功,则它的左子树和右子树都要判断,不论它们存不存在,因为此BTreeCreate调用,输入正整数,即节点创建成功后,都会去创建的left和right。

示例:就上面的程序,在第38行设置断点,依次输入1,2,-1,3,-1,-2,-3,tree指针的存储结构如下(也就是树的存储结构)

根据输入的数据,可以划出如下树的结构图:

对比上面的内存存储情况,可以看得很明白,蓝色的圈圈就是真正的树节点。树的构建过程如下:

输入1,创建主节点,接下来创建1的左子树,创建1右子树的函数等待,设函数入口地址为ad1

输入2,主节点1的左子树创建成功,接下来创建2的左子树,创建2右子树的函数等待,设函数入口地址为ad2

输入-1,节点2的左子树创建失败,返回执行等待的的函数(离当前最近的),即ad2,创建节点2的右子树

输入3,节点2的右子树创建成功,接下来创建节点3的左子树,创建3右子树的函数等待,函数入口地址ad2

。。。。。。

直到函数递归调用完毕,没有等待的函数为止。

下面创建一个完全二叉树验证结果,树的结构图下:

输入:1,2,4,-1,-2,5,-3,-4,3,-5,-6,树的内存存储如下: