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++二叉树搜索树操作集
啥是二叉查找树 在数据结构中,有一个奇葩的东西,说它奇葩,那是因为它重要,这就是树.而在树中,二叉树又是当中的贵族.二叉树的一个重要应用是它们在查找中的应用,于是就有了二叉查找树. 使二叉树成为一颗二 ...
随机推荐
- JavaWeb过滤器.监听器.拦截器-原理&区别(转)
1.拦截器是基于java的反射机制的,而过滤器是基于函数回调 2.过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 3.拦截器只能对action请求起作用,而过滤器则可以对几乎所有的 ...
- C++ 函数模板重载
函数模板可以像普通函数那样重载. C++ 编译器会从不同的候选中匹配一个并进行调用. 即使不涉及到模板,这种匹配的规则也很复杂,现在还有加上模板一起匹配. 先来个小例子: #include <i ...
- 利用Navicate把SQLServer转MYSQL的方法(连数据)
中文乱码问题:https://pqcc.iteye.com/blog/661640 本次转换需要依赖使用工具Navicat Premium. 首先,将数据库移至本地SQLServer,我试过直接在局域 ...
- gitlab 建立本地仓库
1.首先在gitlib上进行注册 注册与登录 为了用户的隐私,我们的私人 GitLab 平台关闭了自主注册.申请 GitLab 账号请联系工作站管理员:liuhaoyang@pku.edu.cn 初次 ...
- 把去世的亲友做成聊天机器人,就能让生者慰藉、死者安息吗? - 看了 寻梦历险记,我的回答是 :是的,他/她永远活在我们心里 www.iremember.com.cn
AppU 如今的我们,之所以离不开手机和互联网,是因为它们确实可以带来信息和方便,让我们轻松记录并分享自己的生活体验,留下了充满回忆的各种文字.语音,各种图片.视频…… 但你有没有想过,当我们逝世时, ...
- Django admin 自定义Choice_field
在使用Django Admin后台时,有时候想自定义某一字段的Choice_field,例如屏蔽某些选项,只显示某些指定的选项. 想象这样的应用场景,我有一个网站,导航栏是这样的: 点开“技术杂谈”后 ...
- python使用requests发送application/x-www-form-urlencoded请求数据
def client_post_formurlencodeddata_requests(request_url,requestJSONdata): #功能说明:发送以form表单数据格式(它要求数据名 ...
- Linux 文件系统剖析
[转自]https://www.ibm.com/developerworks/cn/linux/l-linux-filesystem/ 按照分层结构讨论 Linux 文件系统 在文件系统方面,Linu ...
- crt sqlplus 中文乱码解决方案:
1.确定数据库字符集 SQL> select userenv('language') from dual; USERENV('LANGUAGE') ----------------------- ...
- 命令行部署SharePoint2016离线前提条件和添加服务器的Feature
前言 Sp2016的软件环境要求如下: 服务器场中的数据库服务器的最低要求: 以下各项之一: Microsoft SQL Server 2014 Service Pack 1 (SP1) 的 64 位 ...