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++二叉树搜索树操作集
啥是二叉查找树 在数据结构中,有一个奇葩的东西,说它奇葩,那是因为它重要,这就是树.而在树中,二叉树又是当中的贵族.二叉树的一个重要应用是它们在查找中的应用,于是就有了二叉查找树. 使二叉树成为一颗二 ...
随机推荐
- 10个最好的免费PS图象处理软件方案
说到照片和图像编辑/操纵,真的没有更好的应用,Adobe PS图象处理软件. 摄影师和创意工作室会同意这是总理的照片编辑应用期. 不幸的是,PS图象处理软件还配备了一个陡峭的学习曲线和价格标签,我们必 ...
- 强化学习-MDP(马尔可夫决策过程)算法原理
1. 前言 前面的强化学习基础知识介绍了强化学习中的一些基本元素和整体概念.今天讲解强化学习里面最最基础的MDP(马尔可夫决策过程). 2. MDP定义 MDP是当前强化学习理论推导的基石,通过这套框 ...
- 记录一下idea自动生成Entity
最近在鼓捣spring -boot ,真好用,学习到jpa. 通过生成Entity 文件,能够快速的生成数据库,并且使用 JpaRepository 的基本增删查改 方法,好用的一批. 可是随之,问题 ...
- Oracle分析函数-nulls first/nulls last
select * from criss_sales; 通过rank().dense_rank().row_number()对记录进行全排列.分组排列取值但有时候,会遇到空值的情况,空值会影响得到的结果 ...
- JSP之开发环境搭建
1.下载JDK1.8(或JDK1.7),并进行安装和配置,主要是配置环境变量JAVA_HOME及Path. 2.下载并配置Tomcat8.0(或Tomcat7.0). Windows平台请下载Tomc ...
- 消息中间件系列一:入门、JMS规范、ActiveMQ使用
一.入门 1. 消息中间件的定义 没有标准定义,一般认为,采用消息传送机制/消息队列 的中间件技术,进行数据交流,用在分布式系统的集成 2. 为什么要用消息中间件 解决分布式系统之间消息的传递.电商场 ...
- 树莓派mariadb 设置密码
参考: sudo mysql -u root -p select Host,User,plugin from mysql.user where User='root'; plugin(加密方式)是un ...
- tensorflow简单记录summary方法
虽然tf官方希望用户把 train , val 程序分开写,但实际开发中,明显写在一起比较简单舒服,但在保存数据到 summary 时, val 部分和 train 部分不太一样,会有一些问题,下面讨 ...
- python 将函数参数一键转化成字典的技巧,非**kwargs,公有方法和函数抵制kwargs。
1.有时候使用设计模式,例如工厂方法模式,函数传的参数还需要一一根据条件传递到各个类里面去实例化或者其他原因,直接复制所有的参数看起来不太好,造成很多相同的行. 2.直接函数/方法中写**kwargs ...
- iOS开发之--属性关键字以及set和get方法
一.属性分为三大类 1.读写性控制 a.readOnly只读,只会生成get方法,不会生成set方法 b.readWrite可读可写,会生成set方法,也会生成get方法(默认设置) 2.setter ...