1. 程式人生 > >C++ BST-Binary Search Tree 二叉搜尋樹的實現

C++ BST-Binary Search Tree 二叉搜尋樹的實現

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