BST-二叉查找树
2016-08-25 17:17
260 查看
二叉查找树相比AVL和红黑树简单多了,在删除时无需旋转,但树高不平衡,有可能出现树高 = 结点树的情况,本文介绍其C/C++代码实现。
定义
实现
结点
插入
查找
删除
更新
遍历
测试
任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
任意节点的左、右子树也分别为二叉查找树;
没有键值相等的节点。
样例如图
特点是它的插入删除查找的平均复杂度都是O(log n),当节点有序的时候退化成链表O(n)复杂度(树的全部结点都只有左/右子树)
注意需要返回插入后新树的根节点,不能返回插入点的指针。
删除点没有儿子(也就是叶子),直接删之。
删除点有一个儿子,若有左儿子则把 将删除点的父结点跟左儿子连起来,右儿子同理。
删除点有左右儿子,我们选一个比删除点次大的点来顶替就行,次大可以是:左子树里的最大(左子树里的最右) 或者 右子树里的最小(右子树里的最左)。
如下图,图中的第三种情况是取右子树里的最小替换删除点,下面代码是取左子树里的最大。图片原地址戳这
实现中我们需要让删除点的父亲指向删除点的儿子,但我们没有父节点指针怎破?可以用递归实现,
为了更好理解,请戳这个数据结构动态演示链接:
http://www.cs.usfca.edu/~galles/visualization/BST.html
参考
https://www.topcoder.com/community/data-science/data-science-tutorials/an-introduction-to-binary-search-and-red-black-trees/
http://www.cppblog.com/cxiaojia/archive/2016/02/27/186752.html
推荐两个数据结构演示 地址1 地址2
定义
实现
结点
插入
查找
删除
更新
遍历
测试
定义
直接上维基百科,要么是空树要么是符合以下性质的二叉树任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
任意节点的左、右子树也分别为二叉查找树;
没有键值相等的节点。
样例如图
特点是它的插入删除查找的平均复杂度都是O(log n),当节点有序的时候退化成链表O(n)复杂度(树的全部结点都只有左/右子树)
实现
结点
struct node { int val; node *left, *right; };
插入
插入很简单,根据树的大小关系去左/右定位即可,插入的点一定是新结点/没有子树的。注意需要返回插入后新树的根节点,不能返回插入点的指针。
// 插入:值不可重复,返回插入后的根节点 node* insert(node *root, int val) { if (!root) { root = new node(); root->val = val; } else if (root->val < val) { root->right = insert(root->right, val); } else if (root->val > val) { root->left = insert(root->left, val); } return root; }
查找
非递归写法会明显快于递归写法,不需要压/弹系统栈,若不存在返回NULL即可。// 查找:返回具有该值的结点指针 node* find(node *root, int val) { while (root) { if (root->val < val) { root = root->right; } else if (root->val > val) { root = root->left; } else { return root; } } return NULL; }
删除
删除分三种情况:删除点没有儿子(也就是叶子),直接删之。
删除点有一个儿子,若有左儿子则把 将删除点的父结点跟左儿子连起来,右儿子同理。
删除点有左右儿子,我们选一个比删除点次大的点来顶替就行,次大可以是:左子树里的最大(左子树里的最右) 或者 右子树里的最小(右子树里的最左)。
如下图,图中的第三种情况是取右子树里的最小替换删除点,下面代码是取左子树里的最大。图片原地址戳这
实现中我们需要让删除点的父亲指向删除点的儿子,但我们没有父节点指针怎破?可以用递归实现,
root->right = del(root->right, val);del() 返回删除点的儿子,然后通过上一层去修改指针。
为了更好理解,请戳这个数据结构动态演示链接:
http://www.cs.usfca.edu/~galles/visualization/BST.html
// 删除 返回删除后的根节点 // 情况1:同时有左右儿子,找到左儿子里的最大值,替换上来 // 情况2:有0或1个儿子,有左儿子就让左儿子替换当前节点,有右则右替换,都没有就直接删除 node* del(node *root, int val) { if (!root) return NULL; if (root->val < val) { root->right = del(root->right, val); } else if (root->val > val) { root->left = del(root->left, val); } else { node *son; if (root->left && root->right) { //左右都有,返回左子树里的最右,指针修改由上一层递归处理 son = root->left; while (son->right) son = son->right; son->right = root->right; //避免丢了删除点的右子树 } else { //只有一个子树,返回存在的那个子树即可 if (root->left) son = root->left; else if (root->right) son = root->right; else son = NULL; //叶子结点没有子树,返回NULL给一层 } delete root; //删除点 return son; } return root; }
更新
由于BST没有像其他树那样的调整操作,所以只能先删后增。// 更新值:返回新树根节点 node* update(node *root, int oldVal,int newVal) { root = del(root,oldVal); root = insert(root,newVal); return root; }
遍历
// 中序遍历:得出递增结果 void inOrder(node *root) { if (!root) return; inOrder(root->left); printf("%d ", root->val); inOrder(root->right); }
测试
int main() { node *rt = NULL; rt = insert(rt, 3); rt = insert(rt, 5); rt = insert(rt, 6); rt = insert(rt, 6); rt = insert(rt, 8); rt = insert(rt, 4); rt = insert(rt, 10); inOrder(rt); printf("\n"); rt = del(rt, 6); inOrder(rt); printf("\n"); rt = del(rt,3); inOrder(rt); printf("\n"); rt = update(rt,5,88); inOrder(rt); printf("\n"); return 0; }
参考
https://www.topcoder.com/community/data-science/data-science-tutorials/an-introduction-to-binary-search-and-red-black-trees/
http://www.cppblog.com/cxiaojia/archive/2016/02/27/186752.html
推荐两个数据结构演示 地址1 地址2
相关文章推荐
- 二叉查找树BST和红黑树,果然。。。
- 二叉查找树(BST)AS3版
- 二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree)的比较
- 数据结构: 二叉查找树(BST)
- 二叉查找树BST(1)
- 最优二叉查找树-optimal-BST--C++实现
- 最优二叉查找树-optimal-BST--C++实现2
- 判断整数序列是不是二叉查找树(BST)的后序遍历结果
- 二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree)的比较
- 二叉查找树(BST)和平衡二叉查找树(AVL)
- BST二叉查找树
- java——二叉查找树(BST)算法
- 二叉查找树(binary search tree (BST))--算法导论示例
- 二叉查找树(binary search tree (BST))--算法导论示例
- 递归建立二叉查找树(BST)以及递归求树的高度
- Java实现BST(二叉查找树)
- 二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree)的比较
- 二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree)的比较
- 二叉查找树BST----java实现
- 【JAVA/读书随笔】Chapter 26 二叉查找树(BST)