STL源码—二叉树查找树
来源:互联网 发布:老男孩 linux 编辑:程序博客网 时间:2024/06/05 13:28
为了进一步了解RB树,先了解一下二叉查找树
定义:
二叉查找树是一棵二叉树,因此可以用链式结构来存储数据。若二叉查找树不为空,则应具有以下性质:
- 关键字的值唯一
- 若左子树不为空,则子树任何节点关键字值一定小于其根节点的关键字值
- 若右子树不为空,则子树任何节点关键字值一定大于其根节点的关键字值
- 左、右子树任然是二叉查找树
结构示意图
查找节点:
- 若二叉查找树为空,则查找失败
- 若该树非空且查找数据x等于根节点的值,则查找成功,返回根节点
- 若该树非空且查找数据x小于根节点的值,则查找左子树,直到值相等,并返回节点
- 若该树非空且查找数据x大于根节点的值,则查找右子树,直到值相等,并返回节点
插入节点:
- 若二叉查找树为空,则将结点作为根节点插入
- 若所插入节点关键字值等于根节点的值,则插入失败,并返回
- 若所插入节点关键字值小于根节点的值,则把节点插入到左子树中
- 若所插入节点关键字值大于根节点的值,则把节点插入到右子树中
删除节点:
- 若p结点为叶子结点,则删去该叶子结点,修改其双亲结点的指针即可。
- 若p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点的左子树(当p是左子树)或右子树(当p是右子树)。
- 若p结点的左子树和右子树均不空。找出节点p的后继节点y(一定在节点p的右子树中),以右子树中的最小数作为后继节点。
#include<stdio.h>#include<stdlib.h>#include<malloc.h>#define LENGTH 11struct BinSearNode{int key;struct BinSearNode *left_child;struct BinSearNode *right_child;struct BinSearNode *parent;}Node;typedef struct BinSearNode *PNode;/*Search the node of the tree*/PNode Search_Tree(PNode root,int key){PNode x=root;//the tree is not empty and the key is not equalwhile(NULL!=x && x->key!=key){if(x->key<key)x=x->right_child;//along the right child of tree,until it is emptyelsex=x->left_child;//along the left child of tree,until it is empty}return x;//return the node}/*the minimum key of node in the tree*/PNode Minimum_Tree(PNode root){PNode x=root;while(NULL!=x->left_child){x=x->left_child;}return x;}/*the maxmum key of node in the tree*/PNode Maxmum_Tree(PNode root){PNode x=root;while(NULL!=x->right_child){x=x->right_child;}return x;}/*the successor node of the x,后继节点可以这么理解,将查找树从小到大排序,比他大的值如果有右孩子,那么应该是右子树当中的最小值如果没有右孩子,那么应该向上追溯,直至一个分支节点是其父节点的左孩子,返回父节点可以用于operate++*/PNode Successor_Tree(PNode x){PNode y=NULL;//case 1:the right subtree of node x is not emptyif(NULL!=x->right_child){y=Minimum_Tree(x->right_child);}//case 2:the right subtree of node x is empty//and the node of x has a successor node yelse{y=x->parent;while(NULL!=y && x==y->right_child) {x=y;y=y->parent;}}return y;}/*the predecessor node of the x,前任节点如果节点有左孩子,那么找到左孩子的最大值如果没有左孩子,那么向上追溯直至一个分支当前节点是对应父节点的右孩子,返回父节点的值*/PNode Predecessor_Tree(PNode x){PNode y=NULL;//case 1:the left subtree of node x is not emptyif(NULL!=x->left_child){y=Maxmum_Tree(x->left_child);}//case 2:the left subtree of node x is empty//and the node of x has a predecessor node yelse{y=x->parent;while(NULL!=y && x==y->left_child){x=y;y=y->parent;}}return y;}/*insert a new node into the BST*/void Insert_Tree(PNode *root,int key){PNode x=*root;PNode y=NULL;PNode z=(PNode)malloc(sizeof(Node));//<开辟一个节点的空间if(NULL==z){printf("malloc the z is failed.");exit(1);}//initial the node of zz->key=key;z->left_child=z->right_child=z->parent=NULL;//Find the location node of y to insert the node of zwhile(NULL!=x){y=x; //<找到当前树满足条件的叶子节点了,表示为y,之后在y节点后面进行插入操作if(z->key<x->key)x=x->left_child;elsex=x->right_child;}//insert the node of zz->parent=y;if(NULL==y)*root=z;//tree was emptyelse{if(z->key<y->key)y->left_child=z;elsey->right_child=z;}}void Transplant(PNode *root,PNode u,PNode v){if(NULL==u->parent)*root=v;else{if(u==u->parent->left_child)u->parent->left_child=v;elseu->parent->right_child=v;}if(NULL!=v)v->parent=u->parent;}/*delete a node in the binary search tree*/void Delete_Tree(PNode *root,int key) //<删除节点{//Find the node you want to deletePNode p=Search_Tree(*root,key);if(NULL==p->left_child)Transplant(root,p,p->right_child);else{if(NULL==p->right_child)Transplant(root,p,p->left_child);else{PNode y=Successor_Tree(*root);if(y->parent!=p){Transplant(root,y,y->right_child);y->right_child=p->right_child;y->right_child->parent=y;}Transplant(root,p,y);y->left_child=p->left_child;y->left_child->parent=y;}}}/*print the key of binary search tree*/void ioder_Tree(PNode root){if(NULL!=root){ioder_Tree(root->left_child);printf(" %d",root->key);ioder_Tree(root->right_child);}}int main() { int i; int Arr[LENGTH]={16,6,20,2,7,19,22,1,4,11,8}; PNode root=NULL; PNode p=NULL; for(i=0;i<LENGTH;i++) { Insert_Tree(&root,Arr[i]); } ioder_Tree(root); printf("\n"); //printf("Hello world!\n"); Delete_Tree(&root,11); ioder_Tree(root); printf("\n"); p=Maxmum_Tree(root); printf("The Maxmum of node is:%d\n",p->key); p=Minimum_Tree(root); printf("The Minimum of node is:%d\n",p->key); return 0; }
结果图:
在STL中除了要求是搜索二叉树之外,还需要是平衡搜索二叉树:
因为关联容器很重要的一个是搜索效率
平衡树有很多种比如AVL_tree,RB-tree,AA-tree
平衡二叉树插入节点和删除节点的平均时间都是比较长,但是他们可以很好的避免难以应付的最坏情况
AVL-tree要求任何节点的左右子树的高度相差最多为1
如果插入或者删除操作打破了这些平衡条件,那么这样的树应该需要做相应的旋转操作来达到平衡
RB-tree的节点有红色和黑色的区分,并有一些限制条件,之后会专门进行介绍
0 0
- STL源码—二叉树查找树
- 二叉查找树定义与C源码
- 二叉查找树的各种操作源码
- 【学习点滴-数据结构-二叉树】二叉查找树源码实现
- STL学习笔记之容器--二叉查找树
- poj2418 Hardwood Species STL熟悉+二叉查找树
- 查找--二叉查找树
- 查找算法——二叉树查找
- 查找算法——二叉查找树
- STL源码笔记(18)—平衡二叉树AVL(C++封装+模板)
- 二叉树、二叉查找树
- 二叉树 & 二叉查找树
- 【查找结构】二叉查找树
- 查找之二叉树查找
- 查找之二叉树查找
- 查找:二叉查找树总结
- 二叉树查找树...
- 二叉树查找树
- IIS支持exe文件下载配置方法附图
- setregid
- web 开发笔记”A标签去掉下划线“
- poj 1659 Frogs' Neighborhood (Havel-Hakimi定理,判断序列是否可图)
- JavaScript Array 对象
- STL源码—二叉树查找树
- Android SlidingMenu 使用详解
- switch括号与不加括号
- BootStrap JavaScript插件-模态框
- MYSQL学习笔记1
- android中SharedPreferences的用法
- BIEE JavaHost组件启动状态为status
- java中split() 、replace()、 replaceAll()三个函数分析
- POJ 题目1422 Air Raid(二分图最小路径覆盖)