C++ BST-Binary Search Tree 二叉搜尋樹的實現
阿新 • • 發佈:2018-12-05
BST 二叉搜尋樹(binary search tree)
二叉搜尋樹只能為空樹,或者是具有下列性質的二叉樹
- 若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
- 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;
- 它的左、右子樹也分別為二叉排序樹
樹節點
//Tree_Node.h
#pragma once
struct TreeNode
{
int val;
TreeNode* left = nullptr;
TreeNode* right=nullptr;
TreeNode* parent = nullptr;
TreeNode(int v) :val(v) { };
};
BST樹
//Binary_Search_Tree.h
#pragma once
#include"Tree_Node.h"
#include<vector>
#include<iostream>
class BST
{
private:
TreeNode* _root=nullptr;
//typedef TreeNode Node;
void _createBST( std::vector<int>vec);
TreeNode* _find(int k);
void _insertnode (int a);
void _removenode( int a);
void _inorderprint(TreeNode * node);
void _preorderprint(TreeNode * node);
void _postorderprint(TreeNode * node);
//void _destory();
TreeNode* Predecessor(int a);//尋找前驅節點
TreeNode* Successor(int a);//尋找後繼節點
public:
BST() {};
BST(std::vector<int>vec) { _createBST ( vec); };
//~BST() { _destory(); };
void inorderprint() { _inorderprint(_root); };
void preorderprint() { _preorderprint(_root); };
void postorderprint() { _postorderprint(_root); };
void insert(int a) { _insertnode(a); };
void remove(int a) { _removenode( a); };
};
//vector<int>構造BST
void BST::_createBST(std::vector<int>vec)
{
for (int val : vec)
_insertnode(val);
}
//查詢key的結點
TreeNode* BST::_find(int key)
{
TreeNode* cur=_root;
while (cur->val!=key && cur!=nullptr)
{
if (key > cur->val)
cur = cur->right;
else
cur = cur->left;
}
if(cur!=nullptr)
return cur;
else
{
std::cout << "BST do not have this node!\n ";
return nullptr;
}
}
//插入結點
void BST::_insertnode(int a)
{
TreeNode* node = new TreeNode(a);
if (_root == nullptr)
{
_root = node;
return;
}
else
{
TreeNode* cur = _root;
while (true)
{
//新結點的值大於當前結點cur
if (node->val > cur->val)
{
if(cur->right!=nullptr)
cur = cur->right;
else
{
cur->right = node;
node->parent = cur;
return;
}
}
//新結點的值小於當前結點cur
else
{
if (cur->left!= nullptr)
cur = cur->left;
else
{
cur->left = node;
node->parent = cur;
return;
}
}
}
}
}
//尋找前驅節點
TreeNode* BST::Predecessor(int a)
{
TreeNode* cur = _find(a);
if (cur->left != nullptr)
{
cur = cur->left;
while (cur->right != nullptr)
cur = cur->right;
return cur;
}
while (cur->parent != nullptr && cur->parent->left == cur)
cur = cur->parent;
return cur->parent;
}
//尋找後繼節點
TreeNode* BST::Successor(int a)
{
TreeNode* cur = _find(a);
//cur右結點不為空,則cur後繼結點為右子樹最靠左的結點
if (cur->right != nullptr)
{
cur = cur->right;
//存在左子樹
while (cur->left != nullptr)
cur = cur->left;
return cur;
}
//cur的右結點不存在左子樹,向上找父節點第一個有右孩子且不存在cur的祖先
while (cur->parent != nullptr && cur->parent->right != cur)
cur = cur->parent;
return cur->parent;
}
//刪除值為a的結點
void BST::_removenode(int a)
{
if (_root == nullptr)
throw("error : it's an empty BSTtree!\n");
TreeNode* dnode = _find(a);//找出需要刪除的結點dnode
TreeNode* temp;//temp為取代dnode的結點
if (dnode->left == nullptr && dnode->right == nullptr)//情況1,刪除節點為子節點
temp = nullptr;
else if (dnode->left == nullptr || dnode->right == nullptr)//情況2,刪除節點只有左或者右子樹
{
temp = (dnode->left == nullptr) ? dnode->right : dnode->left;
temp->parent = dnode->parent;
}
else
{
temp = Successor(a);
TreeNode* temp_right;
if (temp->right == nullptr)
temp_right = nullptr;
else
{
temp_right = temp->right;
temp_right->parent = temp->parent;
}
if (temp->parent->right == temp)
temp->parent->right = temp_right;
else
temp->parent->left = temp_right;
//temp取代dnode,注意dnode為根節點情況
if (dnode->parent == nullptr)
{
temp->right = dnode->right;
temp->left = dnode->left;
_root = temp;
delete dnode;
}
else if (dnode->parent->right == dnode)
{
dnode->parent->right = temp;
temp->parent = dnode->parent;
temp->right = dnode->right;
temp->left = dnode->left;
delete dnode;
}
else
{
dnode->parent->left = temp;
temp->parent = dnode->parent;
temp->right = dnode->right;
temp->left = dnode->left;
delete dnode;
}
//或者不取代dnode,將temp和dnode進行資料交換
//dnode->val = temp->val;
//delete temp;
return;
}
//情況1,2餘下操作,注意刪除節點為根節點的特殊情況
if (dnode->parent != nullptr)
{
if (dnode->parent->right == dnode)
dnode->parent->right = temp;
else
dnode->parent->left = temp;
}
else
_root = temp;
delete dnode;
return;
}
//前中後序列印BST
void BST::_inorderprint(TreeNode * node)
{
if (node == nullptr)
return;
std:: cout << node->val << ' ';
_inorderprint(node->left);
_inorderprint(node->right);
}
void BST::_preorderprint(TreeNode * node)
{
if (node == nullptr)
return;
_preorderprint(node->left);
std::cout << node->val << ' ';
_preorderprint(node->right);
}
void BST::_postorderprint(TreeNode * node)
{
if (node == nullptr)
return;
_postorderprint(node->left);
_postorderprint(node->right);
std::cout << node->val<<' ';
}
測試執行結果
//test.cpp
#include"Binary_Search_Tree.h"
#include<iostream>
using namespace std;
int main()
{
vector<int> vec{8,3,10,1,6,4,7,14,13 };
BST bstree(vec);
bstree.inorderprint();
cout<<"\n";
bstree.preorderprint();
cout << "\n";
bstree.postorderprint();
cout << "\ndelete node key = 6\n";
bstree.remove(6);
bstree.preorderprint();
cout << "\ndelete node key = 8\n";
bstree.remove(8);
bstree.preorderprint();
cout << "\ndelete node key = 13\n";
bstree.remove(13);
bstree.preorderprint();
cout << "\n";
system("pause");
return 0;
}
程式碼:
https://github.com/ChristmasError/Data_Structure/tree/master/二叉搜尋樹 BST-Binary Search Tree