有序序列,查找可以使用二分查找,查找容易,但是插入、删除不方便。
二叉排序树使得插入和删除的效率变高,查找也高效进行。
二叉排序树的特点:
1.要么是空树,要么有以下性质
2.左子树如果不空,左子树上所有结点的值都小于根结点
3.右子树如果不空,右子树上所有的结点的值都大于根结点
4.左右子树分别都是二叉排序树
5.二叉排序树的中序遍历是有序的
6.最左边的孩子一定是最小的结点,最右边的孩子一定是最大的结点
注意:二叉排序树是有可能重复的
观察发现:要删除的结点的前驱是第一个左孩子的最右边孩子,后继是第一个右孩子的最左侧孩子,则用任意一个取替换要删除的结点,然后删除替换的那个结点
代码如下:
class BSTNode { public: BSTNode():m_left(nullptr),m_right(nullptr){} BSTNode(int v):m_value(v),m_left(nullptr),m_right(nullptr){} BSTNode* m_left; BSTNode* m_right; int m_value; }; class BSTTree { public: void InsertValueBST(int v) { InsertValueBST(m_root, v); } void InsertValueBST(BSTNode*& root, int v); void InOrder(BSTNode*&root); void print() { InOrder(m_root); cout << endl; } BSTNode* SearchValue(BSTNode*root,int v); BSTNode* SearchValue(int v) { return SearchValue(m_root, v); } BSTNode* GetMin() { return GetMin(m_root); } BSTNode* GetMin(BSTNode* root); BSTNode* GetMax() { return GetMax(m_root); } BSTNode* GetMax(BSTNode*root); void DeleteValue(int v) { DeleteValue(m_root, v); } void DeleteValue(BSTNode*& root, int v); BSTTree():m_root(nullptr){} private: BSTNode* m_root; }; void BSTTree::InsertValueBST(BSTNode*& root, int v)//排序树的插入 { if (root == nullptr) { root = new BSTNode(v);//new一个结点,结点值为v } else if (root->m_value >= v)//如果有重复的数插到左子树 { InsertValueBST(root->m_left, v); } else if(root->m_value < v) { InsertValueBST(root->m_right, v); } } void BSTTree::InOrder(BSTNode*& root)//中序遍历排序树 { if (root != nullptr) { InOrder(root->m_left); cout << root->m_value << " "; InOrder(root->m_right); } } BSTNode* BSTTree::SearchValue(BSTNode* root,int v)//找特定值 { if (root == nullptr) { return nullptr; } else if (root->m_value > v) { return SearchValue(root->m_left, v); } else if (root->m_value < v) { return SearchValue(root->m_right, v); } return root; } void BSTTree::DeleteValue(BSTNode*& root, int v)//删除节点 { BSTNode* tmp = nullptr; if (root != nullptr) { if (root->m_value > v) { DeleteValue(root->m_left, v); } else if (root->m_value < v) { DeleteValue(root->m_right, v); } else if (root->m_left != nullptr && root->m_right != nullptr)//找到该值的结点,且该节点有两个孩子,要删除的结点的前驱是第一个左孩子的最右边孩子,后继是第一个右孩子的最左侧孩子,则用任意一个取替换要删除的结点,然后删除替换的那个结点 { tmp = root->m_left; while (tmp->m_right!=nullptr) { tmp = tmp->m_right; } root->m_value = tmp->m_value; DeleteValue(root->m_left, root->m_value); } else//该节点只要一个孩子或没有孩子 { tmp = root;//tmp记住该节点 if (root->m_left == nullptr)//如果它没有左孩子 { root = root->m_right;//root指向它的右孩子,删掉root结点 } else { root = root->m_left;//root指向它的左孩子,删掉root结点 } delete tmp;//删掉tmp记录的root结点 tmp = nullptr;//置空 } } } BSTNode* BSTTree::GetMax(BSTNode*root)//找最大值 { BSTNode* p = root; if (p != nullptr) { while (p->m_right) { p = p->m_right; } } return p; } BSTNode* BSTTree::GetMin(BSTNode* root)//找最小值 { BSTNode* p = root; if (p != nullptr) { while (p->m_left) { p = p->m_left; } } return p; } void main() { BSTTree t; int num[] = { 62,88,58,47,35,73,5,1,99,37,93 }; int n = sizeof(num) / sizeof(num[0]); for (int i = 0; i < n; i++) { t.InsertValueBST(num[i]); } t.print(); BSTNode* p = t.SearchValue(35); if (p == nullptr) { cout << "没有找到" << endl; } else { cout << "找到了" << p->m_value << endl; } cout << "最大值:" << endl; BSTNode*q=t.GetMax(); cout << q->m_value << endl; cout << "最小值:" << endl; q = t.GetMin(); cout << q->m_value << endl; t.DeleteValue(62); t.print(); }
运行结果:
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交