二叉排序树思想及C语言实现

转自:
http://blog.chinaunix.net/uid-22663647-id-1771796.html 1.二叉排序树的定义   二叉排序树(Binary
Sort Tree)又称二叉查找(搜索)树(Binary Search Tree)。其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树:
①若它的左子树非空,则左子树上所有结点的值均小于根结点的值;②若它的右子树非空,则右子树上所有结点的值均大于根结点的值;③左、右子树本身又各是一棵二叉排序树。
  上述性质简称二叉排序树性质(BST性质),故二叉排序树实际上是满足BST性质的二叉树。2.二叉排序树的性质
按中序遍历二叉排序树,所得到的中序遍历序列是一个递增有序序列。3.二叉排序树的插入 在二叉排序树中插入新结点,要保证插入后的二叉树仍符合二叉排序树的定义。
   插入过程: 若二叉排序树为空,则待插入结点*S作为根结点插入到空树中;   
当非空时,将待插结点关键字S->key和树根关键字t->key进行比较,若s->key =
t->key,则无须插入,若s->key< t->key,则插入到根的左子树中,若s->key>
t->key,则插入到根的右子树中。而子树中的插入过程和在树中的插入过程相同,如此进行下去,直到把结点*s作为一个新的树叶插入到二叉排序树中,或者直到发现树已有相同关键字的结点为止。
4.二叉排序树的查找 假定二叉排序树的根结点指针为 root ,给定的关键字值为 K ,则查找算法可描述为:   ① 置初值: q = root ;   ②
如果 K = q -> key ,则查找成功,算法结束;   ③ 否则,如果 K < q -> key ,而且 q 的左子树非空,则将 q 的左子树根送 q
,转步骤②;否则,查找失败,结束算法;   ④ 否则,如果 K > q -> key ,而且 q 的右子树非空,则将 q 的右子树根送 q
,转步骤②;否则,查找失败,算法结束。5.二叉排序树的删除 假设被删结点是*p,其双亲是*f,不失一般性,设*p是*f的左孩子,下面分三种情况讨论:   
⑴ 若结点*p是叶子结点,则只需修改其双亲结点*f的指针即可。    ⑵ 若结点*p只有左子树PL或者只有右子树PR,则只要使PL或PR
成为其双亲结点的左子树即可。    ⑶
若结点*p的左、右子树均非空,先找到*p的中序前趋(或后继)结点*s(注意*s是*p的左子树中的最右下的结点,它的右链域为空),然后有两种做法:①
令*p的左子树直接链到*p的双亲结点*f的左链上,而*p的右子树链到*p的中序前趋结点*s的右链上。②
以*p的中序前趋结点*s代替*p(即把*s的数据复制到*p中),将*s的左子树链到*s的双亲结点*q的左(或右)链上。 代码实现:
bi_search_tree.h #ifndef __BI_SEARCH_TREE_H__ #define __BI_SEARCH_TREE_H__ /*
*说明:定义了二叉查找树的相关数据结构和几个基本操作 *作者:leaf *时间:2010-09-08 15:55:37 */ typedef int
datatype; struct bi_search_tree { datatype key; struct bi_search_tree
*left,*right; }; typedef struct bi_search_tree bst_tree; /*插入操作,value是待插入的值*/
bst_tree *bst_insert(bst_tree *root, datatype value); /*查找,找到返回1,否则,返回0*/ int
bst_search(bst_tree *root, datatype value); /*删除节点值为value的节点,成功返回1,否则,返回0*/ int
bst_delete(bst_tree *root, datatype value); /*中序输出bst树*/void bst_print(bst_tree
*root); #endif bi_search_tree.c #include #include #include
"bi_search_tree.h" /*插入操作,value是待插入的值*/bst_tree *bst_insert(bst_tree *root,
datatype value) { bst_tree *parent, *node, *child; /*树为空,创建根节点*/
if(root == NULL) { root = (bst_tree *)malloc(sizeof(bst_tree));
root->key = value; root->left = NULL; root->right = NULL;
return root; } parent = root; /*记录下根节点的位置*/ node = root;
while(node != NULL) { /*待插入数据已经存在,则返回*/ if(node->key ==
value) return root; else { parent = node;
/*若小于节点的值,则查看节点的左孩子,否则,查看右孩子*/ if(node->key < value)
node = node->right; else node =
node->left; } } child = (bst_tree *)malloc(sizeof(bst_tree));
child->key = value; child->left = NULL; child->right = NULL;
if(value > parent->key) parent->right = child; else
parent->left = child; return root; } /*查找,找到返回1,否则,返回0*/ int
bst_search(bst_tree *root, datatype value) { bst_tree *p; p = root;
if(p == NULL) return 0; if(p->key == value) return 1;
else if(p->key > value) return bst_search(p->left, value);
else return bst_search(p->right, value); } /*删除节点值为value的节点*/int
bst_delete(bst_tree *root, datatype value) { bst_tree *p, *pre=NULL, *mid;
p = root; if(root == NULL) return 0; /*找到该节点*/
while((p != NULL) && (p->key != value)) { pre = p;
if(p->key < value) { p = p->right; }
else p = p->left; } if(p == NULL) return 0;
/*至少有一个子节点为空*/ if( (p->left == NULL) || (p->right == NULL) ) {
if( pre->left == p ) { pre->left = ( (p->left ==
NULL) ? p->right : p->left ); } else
pre->right = ( (p->left == NULL) ? p->right : p->left );
free(p); /*释放节点*/ } else { /*删除的节点有2个子女*/ mid =
p->right; pre = p; /*寻找中序的第一个节点*/ while(mid->left !=
NULL) { pre = mid; mid = mid->left; }
/*移花接木,直接赋值,避免交换节点*/ p->key = mid->key;
/*将mid节点的子节点作为pre的子节点,并将mid所指向的节点删除*/ if(pre->right == mid)
pre->right = mid->right; else pre->left =
mid->right; free(mid); } return 1; } /*中序输出bst树*/void
bst_print(bst_tree *root) { if(root == NULL) return;
bst_print(root->left); printf(" %d ", root->key);
bst_print(root->right); }测试代码:main.c #include #include
"bi_search_tree.h" int main() { int a[10] = {5,4,2,8,7,1,9,3,6,10}; int
i=0; bst_tree *root=NULL; for(i=0; i<10; i++) root =
bst_insert(root, a[i]); bst_delete(root, 5); bst_print(root);
printf("\n%d %s\n", root->key, bst_search(root, 10) ? "yes":"no"); return
0; }

二叉排序树思想及C语言实现

时间: 2024-11-01 21:24:39

二叉排序树思想及C语言实现的相关文章

C语言的抽象与函数指针--思想(转)

一.何为抽象? 从小到大,我们接触到的抽象,最熟悉的莫过于数学了.为什么这样说呢? 比如说,在小学的时候,老师总是拿了几个苹果来引诱我们:同学们,这里有几个苹果啊?于是我们流着口水一个个地数,一个苹果,两个苹果,三个苹果,然后说三个苹果!第二回,老师又拿了三只葡萄来引诱我们:同学们,这里有几只葡萄啊?于是我们又一只只数过来:一只葡萄二只葡萄三只葡萄,三只葡萄!第三天,老师又拿了三颗糖果来问我们:同学们,这里有几颗糖果啊?我们又数开了:一颗糖果,两颗糖果,三颗糖果!回答:三颗糖果.  每一次老师拿

关于c语言学习 谭浩强的书

2007-11-16 13:22:58|  分类: PROGRAMME |  标签: |举报 |字号大中小 订阅 广大有志于从事IT行业的同志们,在你们进入这一行之前千万请看这篇文章!太经典了!对你绝对有启发! 千万别买谭浩强和等级考试的书!!!!!! 整理别人的言论,请大家踊跃讨论!!!!!!!!!!!! 1:书皮上面有那么多的牛人题词,估计也许是自己的水平太低. 2:ANSI只给了两种方式:int main(void) {/*...*/}和 int main(int argc, char *

苹果新的编程语言 Swift 语言进阶(一)--综述

Swift 是苹果开发和提供的供开发IOS 和OS X应用的一门新的语言.Swift语言基于C 和Objective-C语言,除了提供C 和Objective-C语言具有的所有语法功能外,为了编程方便和高效,Swift在语法上作了大量的优化和改进. Swift采用安全编程模式,具有许多先进的强大的功能 ,如动态运行时.编译动态进行类型检查.Closures.下标功能.自动引用计数.选项类型.通用类型和类型编译时推断.类型的扩展和嵌套.协议类型.功能和类型的通用化.操作符的定制和添加. Swift

C语言实现数据结构之栈的详解

在函数调用的过程中,需要的就是先进后出的特点,因此,栈就出现了. 栈是一种数据结构,是计算机怎么处理程序运行的一种方式.具有先进后出的特点,下面看的就是这些抽象的数据结构怎么用C语言代码来实现,栈能实现,那么其他的数据结构也就自然可以用C语言实现的了,如:队列. C语言实现栈的代码,可以有数组形式,链表形式,下面讲解的是数组形式来实现. 静态数组因为有个大小,而且它在内存的栈区,默认为1M,所以静态数组不会分配的很大,因此用数组来实现,有个栈的容量的问题,自然就会带出"栈顶"和&quo

深入理解C语言

语言只是一种工具,任何语言之间都是想通的,一通则百通,关键是要理解语言背后的思想,理解其思想,任何语言,拿来用就行了.语言没有好坏之分,任何语言既然存在自然有它存在的价值. 在一个到处是OOP的年代,为何面向过程的C语言依然可以如此活跃?这主要得益于C语言本身的语言特性.C语言小巧灵活,而且还有一个直接与硬件打交道的指针的存在,所以它是嵌入式开发唯有的高级语言:正因为他的小巧灵活,我们可以用它来开发一系列的小工具,Unix/Linux就是由这些小工具组成的操作系统:同时用C语言可以开发高性能的应

C语言:关注EOF

EOF是指文件的结束符,是一个宏定义 借助于getchar 与putchar 函数,可以在不了解其它输入/输出知识的情况下编写出数量惊人的有用的代码.最简单的例子就是把输入一次一个字符地复制到输出,其基本思想如下:读一个字符while (该字符不是文件结束指示符)输出刚读入的字符读下一个字符将上述基本思想转换为C语言程序为: #include <stdio.h> main() { int c; c = getchar(); while(c != EOF) { putchar(c); c = g

[技术] 谈谈编程思想

https://zhuanlan.zhihu.com/p/19736530?columnSlug=prattle 作者:陈天链接:https://zhuanlan.zhihu.com/p/19736530来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 这段时间又攒了很多答应了,但还未动手的文章.大概一两周前,有个读者留言:「程序君,能发篇文章有关编程思想的吗?我是编程初学者,对编程思想没啥概念,求传授点经验!」 今天就讲讲编程思想.编程思想是个宏大的主题,我不敢保

辛星漫谈软件思想

之前我也走不出语言的圈子,感觉语言对于软件开发上如此重要,不过一个软件并不应该是依赖生产它的语言,真正让这个软件闪光的是软件本身,并不是生产这个软件的语言. 软件工业的革新速度是绝对的速度和效率,先后出现了N种思想不断的冲击着软件工业,那么我们来看看吧,好吧,我承认可能我写的不全,因为这也是我随手写写,并未经过深思熟虑. 第一种思想就是"语言"这种思想,这种思想太重要了,我感觉从0和1到汇编语言是相当大的一个突破,它开始产生了"语言"的概念,虽然这种所谓的语言只是一

怎样认识语言和思维的关系

人类面对自然界的现实是相同的,大脑的生理构造也一样,因而具有共同的思维能力.任何复杂的现象不同民族的人都有能力认识它.不同民族有共同的思维能力不等于他们有共同的思维方式.思维能力和思维方式是两个不同的概念.思维能力指能不能认识现实,这一点不同的民族没有什么差异,即思维能力是全人类相同的,而思维方式是指如何实现这种能力,这一点不同的民族是不一样的,即思维方式具有民族的特点. 不同民族认识世界的方式是不同的,也就是思维方式上有差别,这些差异我们可以通过对不同语言的比较来加以考察,这些我们从不同民族给