C 二叉查找树的基本操作
最近研究一下二叉树排序问题,找到的资料还真是五花八门,说得也是千奇百怪。
分析一下原因,还是因为数的特性,造成结果的不唯一性造成的大家看了很多,似乎都有理,好像明白了,一综合又糊涂了的结果。
我这里给出一个我自认为很完整,也很精简,也容易理解和应用的框架,可以方便于应用在实际工程里的代码。
————————————————————————————————————————————————————————
排序二叉树的建立、插入、删除、查找
对于排序二叉树,其创建、插入和查找的算法差不多:小了往左,大了往右。
对于二叉排序树,其删除要稍微复杂一点,分成3种基本情况,即
(1)删除的结点是叶子节点
(2)删除结点只有左子树或者只有右子树
(3)删除的结点既有左子树、又有右子树
//bstTest.c
//本例程里采用的是前继承元素替代法实现左右子结点都存在的情况时的删除
// 删除节点左子树的最右边的元素替代之,相当于用前继节点替代
#include "stdio.h"
#include "stdlib.h"
typedef struct _BSTNode
{
int key;
int value;
struct _BSTNode *lchild,*rchild;
}BSTNode,*PBSTNode;
int bst_insert(PBSTNode *pr, int key, int
value)
{
if (!*pr)
{
*pr = (PBSTNode)malloc(sizeof(BSTNode));
if (!*pr)
{
return -1;
}
(*pr)->key = key;
(*pr)->value = value;
(*pr)->lchild=(*pr)->rchild=NULL;
return 0;
}
else if (key==(*pr)->key)
{
return -1;
}
else if (key<(*pr)->key)
{
return bst_insert(&(*pr)->lchild, key, value);
}
else
{
return bst_insert(&(*pr)->rchild, key, value);
}
}
PBSTNode bst_search(PBSTNode r, int key)
{
if (!r)
{
return NULL;
}
PBSTNode p = r;
while (p)
{
if (key<p->key)
{
p = p->lchild;
}
else if (key>p->key)
{
p = p->rchild;
}
else
{
return p;
}
}
return NULL;
}
int bst_remove(PBSTNode *pr, int key)
{
if (!*pr)
{
return -1;
}
if (key==(*pr)->key)
{
PBSTNode p;
if (!(*pr)->lchild&&!(*pr)->rchild)
{
p = *pr;
*pr = NULL;
free(p);
}
else if (!(*pr)->lchild)
{
p = *pr;
*pr = (*pr)->rchild;
free(p);
}
else if (!(*pr)->rchild)
{
p = *pr;
*pr = (*pr)->lchild;
free(p);
}
else
{
// r is just replace with
// max node leftchild tree in
value,
// truely, s is the free node.
PBSTNode pre = *pr;
PBSTNode s = (*pr)->lchild;
while (s->rchild)
{
pre = s;
s = s->rchild;
}
(*pr)->key = s->key;
(*pr)->value = s->value;
if (pre==*pr)
{
(*pr)->lchild = s->lchild;
}
else
{
pre->rchild = s->lchild;
}
free(s);
}
return 0;
}
else if (key<(*pr)->key)
{
return bst_remove(&(*pr)->lchild, key);
}
else
{
return bst_remove(&(*pr)->rchild, key);
}
}
void PreOrderTraverse(PBSTNode r)
{
if (!r)
{
return;
}
printf("%d", r->value);
PreOrderTraverse(r->lchild);
PreOrderTraverse(r->rchild);
}
void MidOrderTraverse(PBSTNode r)
{
if (!r)
{
return;
}
MidOrderTraverse(r->lchild);
printf("%d", r->value);
MidOrderTraverse(r->rchild);
}
void PostOrderTraverse(PBSTNode r)
{
if (!r)
{
return;
}
PostOrderTraverse(r->lchild);
PostOrderTraverse(r->rchild);
printf("%d", r->value);
}
int main()
{
PBSTNode root = NULL;
// build binary search tree
bst_insert(&root, 7, 0);
bst_insert(&root, 3, 1);
bst_insert(&root, 8, 2);
bst_insert(&root, 5, 3);
bst_insert(&root, 9, 4);
bst_insert(&root, 1, 5);
bst_insert(&root, 2, 6);
bst_insert(&root, 4, 7);
bst_insert(&root, 6, 8);
bst_insert(&root, 0, 9);
// mid order traverse
MidOrderTraverse(root);
printf("\n");
// remove node with key to equal 1
if (0==bst_remove(&root, 1))
{
// search node with key to equal 3
PBSTNode p = bst_search(root, 3);
if (p)
{
printf("root %p, 3 node is at %p\n", root, p);
}
}
}
//result
Finally:
在有序结构的查找方面,排序二叉树是效率远高于线性数组的技术,还是非常有用的。
比如,在TCPServer里,因为epoll模型只记录socket,所以在SSL链接里,我们自己的工程里就要建立排序二叉树记录SSL socket,便于高效映射socket。
还是要靠大家自己理解啊!!!“如人饮水,冷暖自知。”
C 二叉查找树的基本操作的更多相关文章
- Scheme实现二叉查找树及基本操作(添加、删除、并、交)
表转化成平衡二叉树 其中有一种分治的思想. (define (list->tree elements) (define (partial-tree elts n) (if (= n 0) (co ...
- 二叉树学习笔记之二叉查找树(BSTree)
二叉查找树即搜索二叉树,或者二叉排序树(BSTree),学习回顾一下有关的知识. >>关于二叉查找树 二叉查找树(Binary Search Tree)是指一棵空树或者具有下列性质的二叉树 ...
- 二叉查找树及B-树、B+树、B*树变体
动态查找树主要有二叉查找树(Binary Search Tree),平衡二叉查找树(Balanced Binary Search Tree), 红黑树 (Red-Black Tree ), 都是典型的 ...
- Java数据结构与算法(4):二叉查找树
一.二叉查找树定义 二叉树每个节点都不能有多于两个的儿子.二叉查找树是特殊的二叉树,对于树中的每个节点X,它的左子树中的所有项的值小于X中的项,而它的右子树中所有项的值大于X中的项. 二叉查找树节点的 ...
- 二叉树学习笔记之B树、B+树、B*树
动态查找树主要有二叉查找树(Binary Search Tree),平衡二叉查找树(Balanced Binary Search Tree), 红黑树 (Red-Black Tree ), 都是典型的 ...
- C++二叉树的实现
C++实现二叉查找树 啥是二叉查找树 在数据结构中,有一个奇葩的东西,说它奇葩,那是因为它重要,这就是树.而在树中,二叉树又是当中的贵族.二叉树的一个重要应用是它们在查找中的应用,于是就有了二叉查找树 ...
- 《剑指offer》内容总结
(1)剑指Offer——Trie树(字典树) Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是统计和排序大量的字符串(但不仅限于字符串),所以经常 ...
- B-树(B+树) 学习总结
一,B-树的定义及介绍 为什么会有B-树? 熟悉的树的结构有二叉树查找树或者平衡二叉树……平衡二叉树保证最坏情况下各个操作的时间复杂度为O(logN),但是为了保持平衡,在插入或删除元素时,需要进行旋 ...
- C/C++二叉树搜索树操作集
啥是二叉查找树 在数据结构中,有一个奇葩的东西,说它奇葩,那是因为它重要,这就是树.而在树中,二叉树又是当中的贵族.二叉树的一个重要应用是它们在查找中的应用,于是就有了二叉查找树. 使二叉树成为一颗二 ...
随机推荐
- pyCoreImage Learn
目录 PyCoreImage 安装 高斯模糊滤镜的例子 使用详细步骤说明 常见操作 滤镜操作 打印所有的滤镜列表 打印某个滤镜的详细信息 使用 zoomBlur 滤镜 使用 mono 滤镜 使用叠加率 ...
- hdoj:2049
#include <iostream> using namespace std; ]; /* n 个 数中 m个错排 转化为:充n个数中选取m个数,共有C(n,m)中,选取的m个数进行全部 ...
- mongo连接拒绝10061原因
首先检查Mongo是否启动: 启动 再次检查mongo配置文件是否允许其他人访问,默认路由是否加上 .进入mongodb安装目录的bin目录,新增mongodb.conf文件,输入 bind_ip=0 ...
- TCP是如何保证可靠传输的
TCP 协议如何保证可靠传输 一.综述 1.确认和重传:接收方收到报文就会确认,发送方发送一段时间后没有收到确认就重传. 2.数据校验 3.数据合理分片和排序: UDP:IP数据报大于1500字节 ...
- classmethod作用
>>> class A(object): bar = 1 def func1(self): print 'foo' >>> class A(object): bar ...
- PXC 57 二进制安装
1.准备阶段 1.1 在三个节点上分别创建:用户组 用户组 目录 --用户组 用户组 #/usr/sbin/groupadd mysql #/usr/sbin/useradd -g mysql mys ...
- CSS设置浏览器滚动条样式
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ ::-webkit-scrollbar { width: 5px; height: 110px; background-color: #F5 ...
- python unittest addCleanup中也加失败截图功能
在python web自动化测试中失败截图方法汇总一文中提到了失败截图的方法 但在实际测试中,如果我们的测试用例中加了addCleanups动作,如果addCleanups中动作失败了,就不会截图.那 ...
- geotrellis使用(四十二)将 Shp 文件转为 GeoJson
前言 一个多月没有写博客了,今天尝试着动笔写点. 原因很多,最重要的原因是我转行了.是的,我离开了开发岗位,走向了开发的天敌-产品经理.虽然名义上是产品经理,但是干的事情也很杂,除了不写代码,其他的都 ...
- git使用——推送本地文件到远程仓库
捣鼓了一下午之后总结如下: 1.首先可以照着这个链接里面博主给出的详细方法进行操作和配置: http://www.open-open.com/lib/view/open1454507333214. ...