本次作业是建立一个Binary Search Tree,二叉搜索树。
二叉搜索树,也叫做排序二叉树,它具有如下性质:若它的左树不为空,则左树上所有节点的值均小于它的根节点值;若它的右子树不空,则右树上所有节点的值均大于它的根节点的值,它的左右子树有分别为二叉搜索树。
首先我们应设置节点的结构:
struct Node{
int val;
Node* left;
Node* right;
Node(int v, Node* l = NULL, Node* r = NULL) : val(v), left(l), right(r) {}
};
接着设计一个Binary Search Tree的类
- class BinarySearchTree {
- public:
- struct Node {
- int val;
- Node* left;
- Node* right;
- Node(int v, Node* l = NULL, Node* r = NULL):
- val(v), left(l), right(r) {
- }
- };
- BinarySearchTree();
- BinarySearchTree(const std::vector<int>&);
- ~BinarySearchTree();
- bool insertNode(int);
- bool searchNode(int);
- bool deleteNode(int);
- void clear();
- Node* getRoot() const;
- private:
- Node* root;
- };
queue<Node*> que;
if (root != NULL) {
que.push(root);
}
while (!que.empty()) {
Node* temp = que.front();
que.pop();
if (temp->left != NULL) {
que.push(temp->left);
}
if (temp->right != NULL) {
que.push(temp->right);
}
delete temp;
}
}
Node* temp = root;
if (temp == NULL) {
temp = new Node(value);
root = temp;
return true;
}
while (temp != NULL) {
if (temp->val == value) {
return false;
} else if (temp->val > value) {
if (temp->left == NULL) {
temp->left = new Node(value);
return true;
} else {
temp = temp->left;
}
} else {
if (temp->right == NULL) {
temp->right = new Node(value);
return true;
} else {
temp = temp->right;
}
}
}
return false;
}
bool BinarySearchTree::searchNode(int value) {
Node* temp = root;
while (temp != NULL) {
if (temp->val == value) {
return true;
} else if (temp->val > value) {
temp = temp->left;
} else {
temp = temp->right;
}
}
return false;
}
最后重点是删除节点的函数,这是本题的关键,因为删除的节点的左右儿子决定了删除节点的方法,一共有三种情况:
1,如果要删除的节点没有左右儿子,则直接删除即可,并前驱设为NULL
2,如果要删除的节点只有左儿子或者右儿子,先标记该节点的前驱和后继,之后删除该节点,并将该节点的后继接到该节点的前驱上。
3,如果要删除的节点既有左儿子也有右儿子,则可以找该节点的左树中值最大的节点或者右树值最小的节点。比如找左树值最大的节点,则将该节点的值与替换要删除的节点的值,标记这个左树最大值节点的前驱和后继,删除这个左树最大值得节点,并将这个左树最大值的节点的后继(如果存在),接到刚刚标记的前驱上面。(注意如果要删除的节点的左树只有一个节点则要另外考虑这种情况)。
下面是该算法的实现:
bool BinarySearchTree::deleteNode(int value) {
Node* temp = root;
Node* parent = root;
while (temp != NULL) {
if (temp->val == value) {
if (temp->left == NULL && temp->right == NULL) {
if (parent->left == temp) {
parent->left = NULL;
} else {
parent->right = NULL;
}
delete temp;
} else if (temp->left == NULL) {
if (parent->left == temp) {
parent->left = temp->right;
} else {
parent->right = temp->right;
}
delete temp;
} else if (temp->right == NULL) {
if (parent->left == temp) {
parent->left = temp->left;
} else {
parent->right = temp->left;
}
delete temp;
} else {
Node* s = temp->left;
Node* q = temp;
while (s->right != NULL) {
q = s;
s = s->right;
}
temp->val = s->val;
if (q != temp) {
q->right = s->left;
} else {
q->left = s->left;
}
}
return true;
} else if (temp->val > value) {
parent = temp;
temp = temp->left;
} else {
parent = temp;
temp = temp->right;
}
}
return false;
}