BST
重点是remove函数
文中“公有”和“私有”同名;调用哪个就看起来迷惑。
inorder其实改为preorder了。
remove中new调用的是私有;Node的构造走的是Node…*
.h文件
#pragma once
#include<iostream>
using namespace std;
template<typename T>
class BST {
private:
//节点类
struct Node {
T value;
Node* left, * right;//指向左右孩子的指针
Node(T value) {
this->value = value;
this->right = this->left = NULL;
}
//用另外一个节点的信息构造节点
Node(Node* node) {
this->value = node->value;//警告出错的地方、、、确实是写错了。。然后、public和private函数名同 调用哪个?本次中掉了private
this->left = node->left;
this->right = node->right;
}
};
private:
Node* root;//BST树的根节点
int size;//BST树总结点个数
/*插入数据域为value的节点,插入之后整个BST任然满足BST的定义
返回值为插入数据域为value节点后,BST树的根节点。*/
Node* insert(Node* node, T value) {
//空树和非空树两种情况
if (node == NULL) {
//空树
size++;//维护树中节点的个数
return new Node(value);
}
else {
//非空树
//树中已有数据域为value的节点,更新该节点、、无用更新
if (value == node->value) {
node->value = value;
return node;
}
else if (value < node->value) {
//value比当前节点的数据域小,根据二叉树的定义,应插入在其左子树中
node->left = insert(node->left, value);
return node;
}
else {
node->right = insert(node->right, value);
return node;
}
}
}
Node* maxValue(Node* node) {
//如果当前节点的右子树为空树,当前节点的数据域即为BST树的最大值
if (node->right == NULL) {
return node;
}
return maxValue(node->right);
}
Node* minValue(Node* node) {
//
if (node->left == NULL) {
return node;
}
return minValue(node->left);
}
//删除最小值后 函数里面不使用&吗???
Node* deleteMin(Node* node) {
/*如果当前节点的左子树为空树,即当前节点的数据域为BST树的最小值。
只需要将当前节点的右子树替代当前节点即可*/
if (node->left == NULL) {
//保存当前节点的右子树
Node* rightTree = node->right;
delete node;
size--;//维护size的定义
return rightTree;
}
else {
//在当前节点右子树树中删除
node->left = deleteMin(node->left);
return node;
}
}
Node* deleteMax(Node* node) { //是和deleteMin相似的代码
if (node->right == NULL) {
Node* leftTree = node->left;
delete node;
size--;
return leftTree;
}
else {
node->right = deleteMax(node->right);
return node;
}
}
Node* remove(Node* node, T value) {
if (node == NULL) {
return node;
}
else {
if (value < node->value) {
node->left = remove(node->left, value);
return node;
}
else if (value > node->value) {
node->right = remove(node->right, value);
return node;
}
else {//value == node->value
if (node->right == NULL) { //先考虑了 没有右孩子;直接换根,node的left顶上
Node* leftTree = node->left;
delete node;
size--;
return leftTree;
}
else if (node->left == NULL) {
Node* rightTree = node->right;
delete node;
size--;
return rightTree;
}
else {
Node* deleteNode = node;
Node* newTree = new Node(minValue(node->right));//右边找“最小的”
newTree->right = deleteMin(node->right);//已经 size--;
newTree->left = node->left;
delete node; //将原来的树 从根开始 删除了???
/*size的数量上来看;、、、建了一棵新树;但是没有和node的parent挂钩啊
:113 yes*/
return newTree;
}
}//else
}
}
//“中序”遍历
void inorder(Node* node) {
if (node != NULL) {
cout << node->value << " ";
inorder(node->left);
inorder(node->right);
}
}
//not good
void destroy(Node* node) {
if (node != NULL) {
destroy(node->left);
destroy(node->right);
delete node;
size--;
}
}
public:
BST() {
root = NULL;
size = 0;
}
~BST() {
destroy(root);//释放以root为根的二叉树节点在heap中的资源
}
//获取当前BST树节点个数
int getSize() { return size; }
//判断一棵BST是否为空树
bool isEmpty() { return size == 0; }
void insert(T value) {
//调用私有的方法,用户只能使用此接口,实现插入操作
root = insert(root, value);
}
//获取BST树中的最大值
T maxValue() {
if (root != NULL) {
Node* maxNode = maxValue(root);//这里公有和私有 同一个函数名;会 调用私有函数吗
return maxNode->value;
}
}
//获取BST树中的最小值
T minValue() {
if (root != NULL) {
Node* minNode = minValue(root);
return minNode->value;
}
}
//删除BST树最大值所在的节点
void deleteMax() {
if (root != NULL) {
root = deleteMax(root);
}
}
void deleteMin() {
if (root != NULL) {
root = deleteMin(root);
}
}
void remove(T value) {
if (root != NULL) {
root = remove(root, value);
}
}
void inorder() {
inorder(root);
}
};
.cpp文件
#include"net bst标头.h"
int main(void) {
int arr[] = { 5,3,4,1,2,8,7,10,0,9,11};
int n = sizeof(arr) / sizeof(int);
BST<int> bst;
for (int i = 0; i < n; ++i) {
bst.insert(arr[i]);
}
bst.inorder();
cout << "max:" << bst.maxValue() << endl;
cout << "min:" << bst.minValue() << endl;
cout << "删除的节点是:value==8" << endl;
bst.remove(8);
bst.inorder();//-842150451 3 1 0 2 4 8 9
cout << endl << "after delete the size is:" << bst.getSize() << endl;
/*都不对!!!*/
cout << "插入 6 后的前序序列" << endl;
bst.insert(6);
bst.inorder();
return 0;
}