歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C++實現搜索二叉樹

C++實現搜索二叉樹

日期:2017/3/1 9:14:26   编辑:Linux編程

二叉查找樹(英語:Binary Search Tree),也稱二叉搜索樹、有序二叉樹(英語:ordered binary tree),排序二叉樹(英語:sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹:

  • 任意節點的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
  • 任意節點的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;
  • 任意節點的左、右子樹也分別為二叉查找樹;
  • 沒有鍵值相等的節點。

#pragma once

template<class K, class V>
struct BSTreeNode
{
K _key;
V _value;
BSTreeNode<K, V>* _left;
BSTreeNode<K, V>* _right;

BSTreeNode(const K& key, const V& value)
:_key(key)
,_value(value)
,_left(NULL)
,_right(NULL)
{}
};

template<class K, class V>
class BSTree
{
typedef BSTreeNode<K, V> Node;
public:
BSTree()
:_root(NULL)
{}

bool Insert(const K& key, const V& value)
{
if (NULL == _root)//若為空樹
{
_root = new Node(key, value);
return true;
}

Node* parent = NULL;
Node* cur = _root;

//確定插入節點的位置
while (cur)
{
if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else//已經存在key
{
return false;
}
}

//插入節點
if (key > parent->_key)
parent->_right = new Node(key, value);
else
parent->_left = new Node(key, value);
}

//Insert遞歸寫法
bool InsertR(const K& key, const V& value)
{
return _InsertR(_root, key, value);
}

bool _InsertR(Node*& root, const K& key, const V& value)
{
if (NULL == root)
{
root = new Node(key, value);
return true;
}

if (key > root->_key)
return _InsertR(root->_right, key, value);
else if (key < root->_key)
return _InsertR(root->_left, key, value);
else
return false;
}

Node* Find(const K& key)
{
Node* cur = _root;

while (cur)
{
if (key > cur->_key)
cur = cur->_right;
else if (key < cur->_key)
cur = cur->_left;
else
return cur;
}

return NULL;
}

//Find遞歸寫法
Node* FindR(const K& key)
{
return _FindR(_root, key);
}

Node* _FindR(Node* root, const K& key)
{
if (NULL == root)
return NULL;

if (key > root->_key)
return _FindR(root->_right, key);
else if (key < root->_key)
return _FindR(root->_left, key);
else
return root;
}

bool Remove(const K& key)
{
Node* parent = NULL;
Node* cur = _root;

//確定刪除節點的位置
while (cur)
{
if (key > cur->_key)
{
parent = cur;
cur = cur->_right;
}
else if (key < cur->_key)
{
parent = cur;
cur = cur->_left;
}
else
{
break;
}
}

if (NULL == cur)//沒有該節點
{
return false;
}

Node* del;
if (NULL == cur->_left)//刪除節點的左孩子為空
{
del = cur;

//刪除的節點為根節點
if (NULL == parent)
{
_root = _root->_right;
}
else
{
if (cur == parent->_left)
parent->_left = cur->_right;
else
parent->_right = cur->_right;
}
}
else if (NULL == cur->_right)//刪除節點的右孩子為空
{
del = cur;

if (NULL == parent)
{
_root = _root->_left;
}
else
{
if (cur == parent->_left)
parent->_left = cur->_right;
else
parent->_right = cur->_left;
}
}
else//刪除節點的左右孩子都不為空,找右子樹最左節點代替該節點刪除
{
parent = cur;

Node* leftmost = cur->_right;
while (leftmost->_left)
{
parent = leftmost;
leftmost = leftmost->_left;
}

del = leftmost;

cur->_key = leftmost->_key;
cur->_value = leftmost->_value;

if (leftmost == parent->_left)
parent->_left = leftmost->_right;
else
parent->_right = leftmost->_right;
}

return true;
}

//Remove遞歸寫法
bool RemoveR(const K& key)
{
return _RemoveR(_root, key);
}

bool _RemoveR(Node*& root, const K& key)
{
if (NULL == root)
return false;

if (key > root->_key)
{
return _RemoveR(root->_right, key);
}
else if (key < root->_key)
{
return _RemoveR(root->_left, key);
}
else
{
Node* del = root;

if (NULL == root->_left)
{
root = root->_right;
}
else if (NULL == root->_right)
{
root = root->_left;
}
else
{
Node* leftmost = root->_right;
while (leftmost->_left)
{
leftmost = leftmost->_left;
}

swap(root->_key, leftmost->_key);
swap(root->_value, leftmost->_value);

return _RemoveR(root->_right, key);
}

delete del;
}

return true;
}

//中序遍歷遞歸寫法
void InOrder()
{
_InOrder(_root);
}

void _InOrder(Node* root)
{
if (NULL == root)
return;

_InOrder(root->_left);
cout<<root->_key<<" ";
_InOrder(root->_right);
}

protected:
Node* _root;
};


void Test()
{
BSTree<int, int> t;
int a[] = {5, 3, 4, 1, 7, 8, 2, 6, 0, 9};
for (size_t i = 0; i < sizeof(a)/sizeof(a[0]);++i)
{
t.InsertR(a[i], i);
}

cout<<t.FindR(8)->_key<<endl;
cout<<t.FindR(5)->_key<<endl;
cout<<t.FindR(9)->_key<<endl;

t.RemoveR(8);
t.RemoveR(7);
t.RemoveR(9);
t.RemoveR(6);
t.RemoveR(5);
t.RemoveR(3);
t.RemoveR(1);
t.RemoveR(4);
t.RemoveR(0);
t.RemoveR(2);

t.InOrder();
}

Copyright © Linux教程網 All Rights Reserved