二叉排序树C语言实现一
来源:互联网 发布:自学plc编程怎么学 编辑:程序博客网 时间:2024/05/16 00:41
一、定义:
二叉排序树(二叉搜索树、二叉查找树)或者是空树,或者满足以下性质:`
(1)若它的左子树非空,则左子树上所有记录的值均小于根记录的值;
(2)若它的右子树非空,则右子树上所有记录的值均大于根记录的值;
(3)左、右子树本身又各是一颗二叉排序树。
——该定义源于《数据结构》李春葆
示例:
二、数据结构:
使用一个链表数据结构来表示,节点定义如下:
typedef struct STnode{ int key;//数据信息 struct STnode *left;//指向左孩子 struct STnode *right;//指向右孩子 struct STnode *p;//指向父节点} STnode;
三、插入操作:
二叉搜索树插入操作比较简单,将欲插入节点my_node从根节点开始比较,用cur_node表示当前被比较的节点,如果my_node.key > cur_node.key,则比较其右孩子,否则比较其左孩子,以此类推,直到找到叶节点为止,将my_node插入(大于所找到的叶节点则作为右孩子插入,小于则作为左孩子插入)。注意:插入操作一定是在叶节点上进的。
示例:插入关键字为9的节点,先和根节点比较(9>6),故与其右孩子节点比较(9>7),继续与其右孩子节点比较(9>8),由于该节点为叶节点,且9>8,则将节点作为右孩子插入。
代码:
//将节点my_node插入到二叉搜索树treeSTnode* STree_Insert(STnode *tree, STnode *my_node){ STnode *parent_node;//指向my_node的父节点 STnode *cur_node;//指向当前被比较的节点 //树为空 if(tree==NULL) tree=my_node; //树不为空 else { parent_node=NULL; cur_node=tree; while(cur_node!=NULL) //while循环寻找my_node的父节点 { parent_node=cur_node; if(my_node->key < cur_node->key) cur_node=cur_node->left; else cur_node=cur_node->right; } my_node->p=parent_node; if(my_node->key < parent_node->key)//插入到左子树 parent_node->left=my_node; else //插入到右子树 parent_node->right=my_node; } return tree;}
四、查找节点
思想比较简单,直接上代码:
//在tree里查找节点my_nodeSTnode *STree_Find(STnode *tree, int my_key){ STnode *cur_node=tree; if(tree==NULL) return NULL; else { while(cur_node->key != my_key) { if(my_key < cur_node->key) cur_node=cur_node->left; else cur_node=cur_node->right; } return cur_node; }}
五、返回最小关键字节点
根据二叉排序树的性质可知,关键字最小的节点一定是整棵树中最左边的节点,所以只需从根节点开始一直寻找left指
针,直到找到NULL为止。
代码:
//返回最小关键字所在节点STnode *STree_Min(STnode *tree){ STnode *cur_node=tree; while(cur_node->left) { cur_node=cur_node->left; } return cur_node;}
六、返回最大关键字所在节点
根据二叉排序树的性质可知,关键字最大的节点一定是整棵树中最右边的节点,所以只需从根节点开始一直寻找right
指针,直到找到NULL为止。
代码:
//返回最大关键字所在节点STnode *STree_Max(STnode *tree){ STnode *cur_node=tree; while(cur_node->right) { cur_node=cur_node->right; } return cur_node;}
七、查找节点后继(中序)
中序序列为:左子树、根、右子树,则一个节点若存在中序后继,则该后继必然位于该节点右边。
下图所示二叉排序树的中序为:2、3、4、6、7、13、15、17、18、20
——该图源于《算法导论》
如上所述,节点的后继一定位于节点右边,分两种情况:
1、该节点右孩子不为空:其后继必然是右子树上的最左节点(如节点6,后继为节点9);
2、该节点右孩子为NULL且该节点为其父节点的左孩子:后继为其父节点(如节点2,后继为节点3);
3、该节点右孩子为NULL且该节点为其父节点的右孩子:后继必为该节点所在“子树”根节点T的父节点,该根节点T
必为其父节点的左孩子,否则继续往上寻找(如节点13,满足该子树根节点为其父节点左孩子的子树根节点为6,
该节点为其父节点15的左孩子,故该节点后继为15)
代码:
STnode *STree_Successor(STnode *my_node){ STnode *cur_node; STnode *successor; if(my_node->right)//右孩子不为空 return STree_Min(my_node->right); else //右孩子为空 { if(my_node==my_node->p->left)//该节点为父节点左孩子 return my_node->p; else//该节点为父节点右孩子 { cur_node=my_node; successor=cur_node->p; while(successor!=NULL && cur_node!=successor->left) { cur_node=cur_node->p; successor=cur_node->p; } return successor; } }}
八、查找节点前驱(中序)
查找节点前驱的算法和查找节点后继的算法对称,也分为三种情况,分析分发一样,直接上代码。
代码:
STnode *STree_Predecessor(STnode *my_node){ STnode *cur_node; STnode *predecessor; if(my_node->left)//左孩子不为空 return STree_Max(my_node->left); else //左孩子为空 { if(my_node==my_node->p->right)//该节点为父节点右孩子 return my_node->p; else//该节点为父节点左孩子 { cur_node=my_node; predecessor=cur_node->p; while(predecessor!=NULL && cur_node!=predecessor->right) { cur_node=cur_node->p; predecessor=cur_node->p; } return predecessor; } }}
七、删除节点
删除节点操作是二叉排序树所有操作中最复杂最难理解的操作,在下一篇博文
(链接地址http://blog.csdn.net/xiaowang627/article/details/51336272 )中对其进行详细的图文描述,
同时对所有函数进行测试。
- 二叉排序树C语言实现一
- 二叉排序树 C语言实现
- C语言实现二叉排序树
- 创建二叉排序树C语言实现
- 二叉排序树C语言实现二
- c语言:二叉排序树的实现
- C语言二叉排序树的实现
- 二叉排序树 遍历 ACM 试题 C语言实现
- C语言二叉排序树单词计数程序实现
- C语言实现二叉排序树的相关操作
- C语言指针实现简单二叉排序树
- pascal语言实现二叉排序树
- 数据结构之---C语言实现二叉排序树(BinarySortTree)
- 二叉排序树(BST)的思路及C语言实现
- C语言实现二叉排序树的增删查操作
- C语言实现二叉排序树的基本运算算法
- C实现二叉排序树
- 二叉排序树C实现
- POJ 1195-Mobile phones(二维树状数组-区间更新区间查询)
- 如果有人问你数据库的原理,叫他看这篇文章
- Cygwin安装
- 黑盒测试和白盒测试
- <MZ&DC联考>D2 T1
- 二叉排序树C语言实现一
- 安卓面试常见问题
- JNI在C 和 C++ 函数实现的去呗
- [LeetCode] Ugly Number
- zoj1245
- javamail验证失败Authentication failed
- spring bean创建细节
- APUE多线程--条件变量
- Android学习资料与学习方法