(第一段日常扯蛋,大家不要看)这几天就要回家了,osgearth暂时也不想弄了,毕竟不是几天就能弄出来的,所以打算过完年回来再弄。这几天闲着也是闲着,就掏出了之前买的算法导论看了看,把二叉搜索树实现了下。
一、算法导论中讲解
1、二叉搜索树
节点
每个节点包含key(关键字)、left(指向左孩子)、right(指向右孩子)、parent(指向父节点)。
额外可有可无num(相同关键字的节点个数)。
规则
整个二叉树的根节点的parent指向NULL,且唯一。
左子树上所有节点的key均小于其根节点的key。
右子树上所有节点的key均大于其根节点的key。
最低层的节点的left与right指向NULL。
2、二叉搜索树的遍历
二叉搜索树的遍历分为先序遍历,中序遍历,后序遍历(由x.key的输出位置决定)。
中序遍历即为按照key从大到小输出。
3、查询二叉树
循环查找
迭代查找
4、最大关键字元素和最小关键字元素
5、后继和前驱
6、插入
对于BST插入只能插入到最下层,例如插入13。
伪代码:
7、删除
删除分为三种情况
1.删除节点的left(或者right)指向NULL,直接把right(或者left)提升到该节点处。
2.删除节点的right和left不为NULL,且其right的left为NULL,直接把right提升到该节点处。
3.删除节点的right和left不为NULL,且其right的left不为NULL,找到删除节点的后继(即大于删除节点key的最小key所在节点y),把后继y的right提到后继y的位置(即让后继y的parent的left指向后继y的right),再用删除节点的right和left分别代替后继y的right和left,最后再用后继y把删除节点替换掉。
伪代码:
节点替换
删除
三、c++代码
#include <iostream> #include <memory> #include <vector> using namespace std; //节点结构 struct Node { int key; int num; shared_ptr<Node> parent; shared_ptr<Node> left; shared_ptr<Node> right; Node(int _key) : key(_key), num(1),parent(NULL), left(NULL), right(NULL) {} }; //循环插入 bool Insert(shared_ptr<Node>& root, int _key) { shared_ptr<Node> node(new Node(_key)); if (root == NULL) { root = node; return true; } shared_ptr<Node> x = root; shared_ptr<Node> y; while(x != NULL) { y = x; if (node->key == x->key) { x->num++; return true; } if (node->key < x->key) x = x->left; else x = x->right; } if (node->key < y->key) { y->left = node; node->parent = y; } else { y->right = node; node->parent = y; } return true; } //迭代插入 bool reInsert(shared_ptr<Node>& root, shared_ptr<Node> node) { if (root == NULL) { root = node; return true; } if (node->key == root->key) { root->num++; return true; } if (node->key < root->key) return reInsert(root->left, node); else return reInsert(root->right, node); } //创建二叉树 void BSTCreat(shared_ptr<Node>& root, vector<int> keys) { for (int key : keys) { Insert(root, key); } } //遍历 void showBST(shared_ptr<Node>& root) { if (root != NULL) { // //cout << root->key << " ";//先序遍历 // showBST(root->left); // cout << root->key << " "; //中序遍历 // showBST(root->right); // //cout << root->key << " ";//后序遍历 //cout << root->key << " "; //first showBST(root->left); cout << root->key << " "; //mid showBST(root->right); //cout << root->key << " "; //end } } //删除节点 bool Delete(shared_ptr<Node>& root, int _key) { if(root == NULL) return false; if(root->key < _key) return Delete(root->right, _key); else if(root->key > _key)return Delete(root->left, _key); else { if (root->right==NULL) { root = root->left; return true; } if (root->left==NULL) { root = root->right; return true; } if (root->right->left==NULL) { root->right->left = root->left; root = root->right; return true; } shared_ptr<Node> y = root->right; while(y->left!=NULL) { y = y->left; } y->parent->left = y->right; y->right = root->right; y->left = root->left; root = y; return true; } } bool isSubtree(shared_ptr<Node> pRootA, shared_ptr<Node> pRootB) { if (pRootB == NULL) return true; if (pRootA == NULL) return false; if (pRootB->key == pRootA->key) { return isSubtree(pRootA->left, pRootB->left) && isSubtree(pRootA->right, pRootB->right); } else return false; } bool HasSubtree(shared_ptr<Node> pRootA, shared_ptr<Node> pRootB) { if (pRootA == NULL || pRootB == NULL) return false; return isSubtree(pRootA, pRootB) || HasSubtree(pRootA->left, pRootB) || HasSubtree(pRootA->right, pRootB); } int main() { vector<int> keys1{1,2,3,4,5,6,7}; vector<int> keys2{3,4,5}; shared_ptr<Node> root1; shared_ptr<Node> root2; BSTCreat(root1, keys1); BSTCreat(root2, keys2); cerr << HasSubtree(root1, root2) << endl; return 0; }