重写数据结构--二叉搜索树
2016-08-19 18:34
204 查看
性质:
根节点左边的节点关键字都比根节点的关键字小;根节点右边的节点关键字都比根节点的关键字大;结构体:
typedef struct BinarySearchTreeNode { int value; BinarySearchTreeNode* parent; BinarySearchTreeNode* left; BinarySearchTreeNode* right; }BinarySearchTreeNode;
按序输出:
中序遍历(复杂度为O(n)):void InOrder(BinarySearchTreeNode* root) { if (root != NULL) { InOrder(root->left); cout << root->value << " "; InOrder(root->right); } }
查找元素:
(递归实现)BinarySearchTreeNode* Search(BinarySearchTreeNode* root, int x) { if (root == NULL || x == root->value) { //感觉这句好机智 return root; } else { if (x > root->value) { return Search(root->right, x); } else { return Search(root->left, x); } } }
(非递归实现)
BinarySearchTreeNode* Search_(BinarySearchTreeNode* root, int x) { while( root!= NULL && x != root->value) { if (x > root->value) { root = root->right; } else { root = root->left; } } return root; }
最小元素和最大元素:
//最小 BinarySearchTreeNode* Min(BinarySearchTreeNode* root) { BinarySearchTreeNode* ans = NULL; while (root != NULL ) { ans = root; root = root->left; } return ans; } //最大 BinarySearchTreeNode* Max(BinarySearchTreeNode* root) { BinarySearchTreeNode* ans = NULL; while (root != NULL ) { ans = root; root = root->right; } return ans; }
寻找前驱和后继:
《算法导论》给出了一个找后继的例子:如果该节点有右子树,直接返回右子树的最小值;
否则沿着该节点向上找双亲,找到一个节点,这个节点是它的双亲的左子树,就返回它的双亲;
但是我觉得更直观的理解是不断向上找双亲,然后直接比较关键字,遇到第一个关键字比寻找的元素大,就终止返回;
他那样写一定有他的理由,因为是直观的去按照中序遍历的思路去寻找,肯定是很完备的;只是目前我找不出我的思路的错误
//算法导论上的实现 BinarySearchTreeNode* FindSuccessor(BinarySearchTreeNode* root) { if (root->right != NULL) { return Min(root->right); } else { BinarySearchTreeNode* ans = root.parent; while(ans != NULL && root == ans->right) { root = ans; ans = ans->parent; } return ans; } }
寻找前驱应该是对称的;
插入和删除:
插入:首先传入的树根一定是引用,其次,先建立一个临时节点便于之后插入,向下索引时(插入的位置一定是NULL),所以要同时记录插入位置的双亲节点,然后再根据大小关系判断插入。
void Insert(BinarySearchTreeNode* &root, int z) { BinarySearchTreeNode* temp = new BinarySearchTreeNode; temp->value = z; temp->parent = temp->left = temp->right = NULL; BinarySearchTreeNode* index = root; BinarySearchTreeNode* index_parent = NULL; while(index != NULL) { index_parent = index; if (temp->value > index->value) { index = index->right; } else { index = index->left; } } temp->parent = index_parent; if (index_parent == NULL) { root = temp; } else if (temp->value > index_parent->value) { index_parent->right = temp; } else { index_parent->left = temp; } }
删除:
被删除节点为z
分三种情况:
z没有孩子,直接删除,并修改双亲结点指向z的指针为NULL
z只有一个孩子,将孩子提到z的位置,并修改双亲结点指向z的指针为z的孩子
z有两个孩子,先找z的后继,如果后继不是z的右子树的根节点,先把后继换到右子树的根节点;接着,把后继提上来,再改变后继的左子树为z的左子树
替换的子过程:
//以v为根的子树替换一棵以u为根的子树,此时u作为一个单独的节点保留自己的信息,但是独立出这棵树了 void TransPlant(BinarySearchTreeNode* & root, BinarySearchTreeNode* u, BinarySearchTreeNode* & v) { if(u->parent == NULL) { root = v; } else { BinarySearchTreeNode* & Parent = u->parent; if (u == Parent->left) { Parent->left = v; } else { Parent->right = v; } } if (v != NULL) { v->parent = u->parent; } }
删除节点:
void Delete(BinarySearchTreeNode* &root, BinarySearchTreeNode* z) { //如果传入的参数是int,那就调用一次Search if (root == NULL) { cout << "Already empty!" << endl; return; } if (z == NULL) { cout << "Not exist!" << endl; return; } if (z->left == NULL) { TransPlant(root, z, z->right); } else if (z->right == NULL) { TransPlant(root, z, z->left); } else { //上两种情况是只有一个子树,或者没有子树,下面的情况是有两个子树 BinarySearchTreeNode* y = Min(z->right); if (y->parent != z) { //如果y不是z的右子树, 把y换到z的右子树 TransPlant(root, y, y->right); y->right = z->right; y->right->parent = y; } TransPlant(root, z, y); y->left = z->left; y->left->parent = y; } }
再次考虑到,什么时候该用引用呢?当需要在函数中改变参数的时候,传参就加上引用;但是遇到很多遍历的情况,会经常不知所措,所以目前采取的策略是,在确保不会错的情况下,只要函数里对这个变量有赋值的操作,我都会加上引用;
构建随机二叉搜索树:
将n个不同的关键字按照随机次序单纯使用插入操作建树;一个有n个不同关键字的随机构建二叉搜索树的期望高度为log(n)
双亲的意义:
用来寻找前驱和后继;和堆&优先队列的区别
堆是左右子树的根节点都会比双亲节点大,并且优先队列插入和删除的操作是不断交换的过程相关文章推荐
- 数据结构 《5》----二叉搜索树 ( Binary Search Tree )
- 二叉搜索树基本数据结构实现
- 【四】nginx的数据结构(2)——自己动手重写红黑树
- 数据结构:二叉搜索树
- 二叉搜索树【数据结构】
- 模板重写数据结构——链表
- C++数据结构: 二叉搜索树 (非递归)
- 【数据结构】二叉搜索树(增、删、查)的递归与非递归实现
- 数据结构:二叉搜索树
- 数据结构中常见的树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)
- 二叉搜索树的基本操作(查找、插入、删除)【数据结构】
- 数据结构--二叉搜索树的实现(C++)
- 【数据结构】二叉搜索树的删除,插入,查找
- 中国大学MOOC-陈越、何钦铭-数据结构 是否同一棵二叉搜索树
- 数据结构学习-二叉搜索树-查找、插入、删除
- 数据结构中常见的树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)
- 数据结构中常见的树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)
- PTA 5-1 是否同一棵二叉搜索树(数据结构)
- hdu 3791:二叉搜索树(数据结构,二叉搜索树 BST)
- 【数据结构】二叉搜索树的递归与非递归实现