|
地板

楼主 |
发表于 2009-9-16 00:25:19
|
只看该作者
二叉树结构数组表示法
二叉树的特性是每个结点至多拥有两个子结点,所以可以声明结构存储树的结点,这个结点至少拥有 3 个数据项,数据项存放结点的数据,另外两个项存放指向左子树和右子树的数据索引:
二叉树使用的结构声明如下:struct tree {
int data;
int left;
int right;
}; 上面的声明,left 表示左结点,如果 left = -1 ,那么表示此结点没有左子结点,如果不是 -1,则表示有左子结点,其值表示在这个子结点上的数据所在原数组中的索引。比如 left = 3,data = 5,这个 data 值是取自一个数组,而 left = 3 表示这个 data 值在它原来所在的数组中的索引为 3 。right 值同理。
下面是测试程序:
#include <stdio.h>
struct tree { /*树的结构声明*/
int data; /*结点数据*/
int left; /*指向左子树的位置*/
int right; /*指向右子树的位置*/
};
typedef struct tree treenode; /*树的结构新类型*/
treenode btree[15]; /*声明树的结构数组*/
/*---------------------*/
/*创建二叉树 */
/*---------------------*/
void createbtree (int *data, int len)
{
int level; /*树的层数*/
int pos; /*-1是左树,1是右树*/
int i;
btree[0].data = data[0]; /*创建树的根结点*/
for (i = 1; i < len; i++) { /*循环创建其它结点*/
btree[i].data = data[i];
level = 0;
pos = 0;
while (pos == 0) {
/*比较是左或右子树*/
if (data[i] > btree[level].data)
/*右树是否有下一层树*/
if (btree[level].right != -1)
level = btree[level].right;
else
pos = -1; /*是右树*/
else
if (btree[level].left != -1)
level = btree[level].left;
else
pos = 1; /*是左树*/
}
if (pos == 1) /*创建结点左右位置*/
btree[level].left = i; /*连接左子树*/
else
btree[level].right = i; /*连接右子数*/
}
}
/*-------------------------------*/
/*主程序:创建结构数组的二叉树结构*/
/*-------------------------------*/
int main()
{
/*二叉树结点数据*/
int data[10] = {5, 6, 4, 8, 2, 3, 7, 1, 9};
int i;
for (i = 0; i < 15; i ++) {
btree[i].data = 0;
btree[i].left = -1;
btree[i].right = -1;
}
createbtree(data, 9);
printf (" 左 数据 右\\n");
for (i = 0; i < 15; i++)
if (btree[i].data != 0)
printf ("%2d:[%2d] [%2d] [%2d]\\n", i, btree[i].left,
btree[i].data, btree[i].right);
return (0);
} 运行与输出:
beyes@linux-beyes:~/C/structer/BinaryTree> ./struct_tree.exe
左 数据 右
0:[ 2] [ 5] [ 1]
1:[-1] [ 6] [ 3]
2:[ 4] [ 4] [-1]
3:[ 6] [ 8] [ 8]
4:[ 7] [ 2] [ 5]
5:[-1] [ 3] [-1]
6:[-1] [ 7] [-1]
7:[-1] [ 1] [-1]
8:[-1] [ 9] [-1] 说明,从 data[10] 这个数组中取出元素建立二叉树。建立二叉树的流程及规律是:
data[0] = 5,这个数据作为二叉树根结点的数据值。接着,取出 data[1] ,因为 data[1] = 6 ,它的值比 5 大,那么此值应放在根结点的右子树上。下一步还需检测右子树是否已经被其他数据占据,如果还没有,那么 pos = -1 ,说明并未有数据占据,那么就讲这个数据的索引号填入到 btree[0].right 中。如果取出的是 data[3] = 8,同样从根结点开始检测,8 比 5 大,那么继续检测 5 的右子树是否被占用(right != -1 表示已经被占用),如果已被(6)占用,那么继续往下检测,发现 8 比 6 大且6的右子树没被占用,于是把 8 插到 6 的右子树上,同时把 8 所在 data 数组中的索引值赋予btree[1].rihgt。
左子树的情况同理可推。
建立完后的二叉树如下图所示:
这种表示法可以解决二叉树插入结点或删除结点时的大量数据移动的问题。因此二叉树的创建是靠字段 left 和 right 连接,上述操作只需改变这两个字段值即可。不过需要估计二叉树的结点个数却是这种表示法的一大问题,否则结点数一旦超过声明的结构数组长度,将会产生未知结果的错误。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|