创建二叉树来实现指路问题
2015-01-19 10:17
218 查看
生活中我们经常会遇到这样的问题,对话如下。路人:“同学,请问湘大图书馆怎么走啊?” 学生:“前面路口左转,然后直走,第三个路口左转,之后再右转就到了。”这里就涉及到创建二叉树来解决此类问题的方法了。
指路法定位结点
从根节点开始:
结点1的位置: { NULL }
结点2的位置: { 左 }
结点3的位置: { 右 }
结点4的位置: { 左,左 }
结点5的位置: { 左,右 }
结点6的位置: { 右,左 }
结点7的位置: { 右,右 }
结点8的位置: { 左,左,左 }
结点9的位置: { 左,左,右 }
结点10的位置: { 左,右,左 }
指路法通过根节点与目标结点的相对位置进行定位,可以通过避开二叉树递归的性质“线性”定位,,在C语言中,我们可以利用bit位进行指路,如下:
二叉树的存储结构是怎么样的呢?用结构体来定义二叉树的指针域,二叉树的头结点也可以用结构体来实现。
结点指针域定义如下:
头结点定义如下:
数据元素定义示例如下:
二叉树的操作
定位如下:
二叉树的实现,代码如下:
View Code
用Dev—C++实现代码的结构如下图,这里仅供大家参考体会。
![](http://images.cnitblog.com/blog/563126/201501/191017321729181.png)
小结:
二叉树在结构上不依赖组织链表;通过指路法可以方便的定位二叉树中的结点;基于指路法的二叉树在插入,删除以及获取操作的实现细节上与单链表相似(单链表就是特殊的二叉树,实现上相似,知识更简单一点啦)
指路法定位结点
从根节点开始:
结点1的位置: { NULL }
结点2的位置: { 左 }
结点3的位置: { 右 }
结点4的位置: { 左,左 }
结点5的位置: { 左,右 }
结点6的位置: { 右,左 }
结点7的位置: { 右,右 }
结点8的位置: { 左,左,左 }
结点9的位置: { 左,左,右 }
结点10的位置: { 左,右,左 }
指路法通过根节点与目标结点的相对位置进行定位,可以通过避开二叉树递归的性质“线性”定位,,在C语言中,我们可以利用bit位进行指路,如下:
#define BT_LEFT 0 #define BT_RIGHT 1 typedef unsigned long long BTPos;
二叉树的存储结构是怎么样的呢?用结构体来定义二叉树的指针域,二叉树的头结点也可以用结构体来实现。
结点指针域定义如下:
typedef struct _tag_BTreeNode BTreeNode; struct _tag_BTreeNode { BTreeNode* left; BTreeNode* right; };
头结点定义如下:
typedef struct _tag_BTree TBTree; struct _tag_BTree { int count; BTreeNode* root; };
数据元素定义示例如下:
struct Node { BTreeNode header; char v; };
二叉树的操作
定位如下:
while( ( count > 0 ) && ( current != NULL ) ) { bit = pos & 1; pos = pos >>1; count--; parent = current; if( bit == BT_LEFT ) { current = current -> left; } elsf if( bit == BT_RIGHT ) { current = current -> right; } }
二叉树的实现,代码如下:
#include <stdio.h> #include <stdlib.h> #include "BTree.h" struct Node { BTreeNode header; char v; }; void printf_data(BTreeNode* node) { if( node != NULL ) { printf("%c", ((struct Node*)node)->v); } } int main(int argc, char *argv[]) { BTree* tree = BTree_Create(); struct Node n1 = {{NULL, NULL}, 'A'}; struct Node n2 = {{NULL, NULL}, 'B'}; struct Node n3 = {{NULL, NULL}, 'C'}; struct Node n4 = {{NULL, NULL}, 'D'}; struct Node n5 = {{NULL, NULL}, 'E'}; struct Node n6 = {{NULL, NULL}, 'F'}; BTree_Insert(tree, (BTreeNode*)&n1, 0, 0, 0); BTree_Insert(tree, (BTreeNode*)&n2, 0x00, 1, 0); BTree_Insert(tree, (BTreeNode*)&n3, 0x01, 1, 0); BTree_Insert(tree, (BTreeNode*)&n4, 0x00, 2, 0); BTree_Insert(tree, (BTreeNode*)&n5, 0x02, 2, 0); BTree_Insert(tree, (BTreeNode*)&n6, 0x02, 3, 0); printf("Height: %d\n", BTree_Height(tree)); printf("Degree: %d\n", BTree_Degree(tree)); printf("Count: %d\n", BTree_Count(tree)); printf("Position At (0x02, 2): %c\n", ((struct Node*)BTree_Get(tree, 0x02, 2))->v); printf("Full Tree: \n"); BTree_Display(tree, printf_data, 4, '-'); BTree_Delete(tree, 0x00, 1); printf("After Delete B: \n"); printf("Height: %d\n", BTree_Height(tree)); printf("Degree: %d\n", BTree_Degree(tree)); printf("Count: %d\n", BTree_Count(tree)); printf("Full Tree: \n"); BTree_Display(tree, printf_data, 4, '-'); BTree_Clear(tree); printf("After Clear: \n"); printf("Height: %d\n", BTree_Height(tree)); printf("Degree: %d\n", BTree_Degree(tree)); printf("Count: %d\n", BTree_Count(tree)); BTree_Display(tree, printf_data, 4, '-'); BTree_Destroy(tree); return 0; }
View Code
用Dev—C++实现代码的结构如下图,这里仅供大家参考体会。
![](http://images.cnitblog.com/blog/563126/201501/191017321729181.png)
小结:
二叉树在结构上不依赖组织链表;通过指路法可以方便的定位二叉树中的结点;基于指路法的二叉树在插入,删除以及获取操作的实现细节上与单链表相似(单链表就是特殊的二叉树,实现上相似,知识更简单一点啦)
相关文章推荐
- 一步一步SharePoint 2007之二十一:解决实现注册用户后,自动具备访问网站的权限的问题(3)——创建用户
- 一步一步SharePoint 2007之二十一:解决实现注册用户后,自动具备访问网站的权限的问题(3)——创建用户
- 二叉树问题C#实现
- 创建二叉树,C语言实现
- js实现动态创建txt框。今天学生问此问题,做个小例子,大家也说说还有什么实现的方法。
- ::递归实现——创建二叉树 ----> 装入数据--->遍历---> 显示 --->销毁
- 二叉树的各种实现(创建,叶子结点数,是否为堆,完全二叉树,二叉查找树,交换左右孩子)
- 不疯魔,不成活!——二叉树的创建、遍历(递归实现)等操作。
- 二叉树的创建以及利用迭代实现中序、先序、后序遍历、清空
- 二叉树的创建及遍历(求问如何实现没有规律的二叉结点树的创建?)
- 递归方法实现二叉树的创建,遍历
- 实现二叉树以及链表发现的问题
- 有关二叉树的相关的问题的实现
- 二叉树的创建,遍历,查找算法及其程序实现(傻瓜版)
- 二叉树的创建,先序、中序、后序遍历的递归实现以及层序遍历
- 一步一步SharePoint 2007之二十一:解决实现注册用户后,自动具备访问网站的权限的问题(3)——创建用户
- 二叉树创建、前序遍历、中序遍历、后序遍历 的 递归与非递归实现 以及 层次遍历
- 二叉树 创建与输出 递归法实现
- C++ 二叉树实现 创建,先序遍历,中序遍历,后序遍历
- 数据结构二叉树的java实现,包括二叉树的创建、搜索、删除和遍历