二叉搜索樹
二叉搜索樹又稱為二叉排序樹,它或者是一棵空樹,或者是具有以下性質(zhì)的二叉樹:
若它的左子樹不為空,
則左子樹上所有結(jié)點(diǎn)的值都小于根結(jié)點(diǎn)的值。
若它的右子樹不為空,
則右子樹上所有結(jié)點(diǎn)的值都大于根結(jié)點(diǎn)的值。
它的左右子樹也分別是二叉搜索樹。
二叉搜索樹的模擬實(shí)現(xiàn)
構(gòu)造函數(shù)
BSTree()
:_root(nullptr)
{
}
拷貝構(gòu)造函數(shù)
BSTree(const BSTree<K>& t)
//BSTree( BSTree<K> *this , const BSTree<K> & t)
//t1 =t
{
_root = Copy(t._root);
}
private:
Node* Copy(Node* root)
{
if (root == nullptr)
{
return nullptr;
}
Node* copyNode = new Node(root->_key);
//遞歸
copyNode->_left = Copy(root->_left);
copyNode->_right = Copy(root->_right);
return copyNode;
}
賦值運(yùn)算符重載函數(shù)
//賦值重載
BSTree<K>& operator= (BSTree<K>& t)
//t1 = t
//深拷貝
{
swap(_root, t._root);
return *this;
}
析構(gòu)函數(shù)
~BSTree()
{
Destroy(_root);
}
private:
void Destroy(Node*& root) //引用的目的:將每個(gè)節(jié)點(diǎn)釋放后同時(shí)置空
{
//后序遍歷
if (root == nullptr)
{
return;
}
Destroy(root->_left);
Destroy(root->_right);
delete root;
root = nullptr;
}
Insert
核心思路:
如果是空樹,則直接將插入結(jié)點(diǎn)作為二叉搜索樹的根結(jié)點(diǎn)。
如果不是空樹,則按照二叉搜索樹的性質(zhì)進(jìn)行結(jié)點(diǎn)的插入。
如果待插入結(jié)點(diǎn)的值<根結(jié)點(diǎn)的值,則需要將結(jié)點(diǎn)插入到左子樹當(dāng)中。
如果待插入結(jié)點(diǎn)的值>根結(jié)點(diǎn)的值,則需要將結(jié)點(diǎn)插入到右子樹當(dāng)中。
如果待插入結(jié)點(diǎn)的值等于根結(jié)點(diǎn)的值,則插入失敗。
循環(huán)
bool Insert(const K & key )
{
//空樹
if (_root == nullptr)
{
_root = new Node(key);
return true;
}
//不是空樹
Node* parent = nullptr;//找到父節(jié)點(diǎn)
Node* cur = _root;
while (cur)
{
//比較
if (cur->_key < key)
{
//往右子樹走
parent = cur;
cur = cur->_right;
}
else if (cur->_key > key)
{
//往左子樹走
parent = cur;
cur = cur->_left;
}
else
{
return false;
}
}
//插入節(jié)點(diǎn)
cur = new Node(key);
//不知道parent在那一邊,需要進(jìn)一步判斷
if (parent->_key > key)
{
//parent在左邊
parent->_left = cur;
}
else if (parent->_key < key)
{
//parent在右邊
parent->_right = cur;
}
else
{
return false;
}
return true;
}
遞歸
bool InsertR(const K& key)//遞歸版本
{
return _InsertR(_root, key);
}
private:
bool _InsertR(Node*& root, const K& key) //引用的目的:不用找父節(jié)點(diǎn),不需要用父節(jié)點(diǎn)比較大小
{
//結(jié)束條件
if (root == nullptr)
{
root = new Node(key);
return true;
}
//往左子樹走
if (root->_key > key)
{
return _InsertR(root->_left, key);
}
//往右子樹走
else if (root->_key < key)
{
return _InsertR(root->_right, key);
}
else
{
return false;
}
}
Erase
先找到需要?jiǎng)h除的節(jié)點(diǎn)
需要?jiǎng)h除的節(jié)點(diǎn)可能會(huì)有三種情況:
1、待刪除結(jié)點(diǎn)的左子樹為空(待刪除結(jié)點(diǎn)的左右子樹均為空包含在內(nèi))
2、待刪除結(jié)點(diǎn)的右子樹為空。
1、2 兩種情況,被刪除的節(jié)點(diǎn)都只有一個(gè)孩子
3、待刪除結(jié)點(diǎn)的左右子樹均不為空,即被刪除節(jié)點(diǎn)有兩個(gè)孩子
使用替換法處理第3中情況:
1、找替換節(jié)點(diǎn):替換節(jié)點(diǎn)一般是左子樹的最大節(jié)點(diǎn)(最右節(jié)點(diǎn)),或者是右子樹的最小節(jié)點(diǎn)(最左節(jié)點(diǎn))
2、將替換的節(jié)點(diǎn)刪除
特殊情況:
循環(huán)
bool Erase(const K& key)
{
Node* parent = nullptr;//待刪除節(jié)點(diǎn)的父節(jié)點(diǎn)
Node* cur = _root;//待刪除的節(jié)點(diǎn)
//不是空樹
while (cur)
{
//往左邊走
if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
//往右邊走
else if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
//找到待刪除的節(jié)點(diǎn)
else
{
//待刪除節(jié)點(diǎn)的左子樹為空 ,即一個(gè)孩子的情況
if (cur->_left == nullptr)
{
//待刪除節(jié)點(diǎn)是根節(jié)點(diǎn)
if (cur == _root)
{
//將根節(jié)點(diǎn)改為待刪除節(jié)點(diǎn)的右孩子
_root = cur->_right;
}
//待刪除節(jié)點(diǎn)不是根節(jié)點(diǎn),并且此時(shí)parent不為nullptr
else
{
if (parent->_right == cur)
{
parent->_right = cur->_right;
}
else//parent->_left ==cur
{
parent->_left = cur->_right;
}
}
}
//待刪除節(jié)點(diǎn)的右子樹為空 ,即一個(gè)孩子的情況
else if (cur->_right == nullptr)
{
//待刪除節(jié)點(diǎn)是根節(jié)點(diǎn)
if (cur == _root)
{
//將根節(jié)點(diǎn)改為待刪除節(jié)點(diǎn)的左孩子
_root = cur->_left;
}
//待刪除節(jié)點(diǎn)不是根節(jié)點(diǎn),并且此時(shí)parent不為nullptr
else
{
if (parent->_right == cur)
{
parent->_right = cur->_left;
}
else//parent->_left==cur
{
parent->_left = cur->_left;
}
}
}
else //待刪除的節(jié)點(diǎn)的左右孩子都不為空 (替換法:左子樹的最大節(jié)點(diǎn)即最右節(jié)點(diǎn),或者右子樹的最小節(jié)點(diǎn)即最左節(jié)點(diǎn),并且將替換的節(jié)點(diǎn)刪除)
{
//替換法
//找替代節(jié)點(diǎn)
Node* parent = cur;
//找左子樹的最大節(jié)點(diǎn),左子樹的最大節(jié)點(diǎn)一定沒有右孩子
Node* leftMax = cur->_left;
while (leftMax->_right)
{
parent = leftMax; //記錄leftMax的父節(jié)點(diǎn),防止刪除leftMax時(shí)找不到該節(jié)點(diǎn)位置
//一直往右子樹找
leftMax = leftMax->_right;
}
//左子樹的最大節(jié)點(diǎn)和待刪除節(jié)點(diǎn)替換
swap(cur->_key, leftMax->_key);
//重新改變鏈接關(guān)系
//特殊情況
if (parent->_left == leftMax)
{
parent->_left = leftMax->_left;
}
else//普通情況 parent->_right== leftMax
{
parent->_right = leftMax->_left;
}
cur = leftMax;
}
//刪除左子樹的最大節(jié)點(diǎn)
delete cur;
return true;
}
}
return false;
}
遞歸
bool EraseR(Node* _root, const K& key)//遞歸版本
{
return _EraseR(_root, key);
}
private:
bool _EraseR(Node*& root, const K& key)//引用的目的:不用找父節(jié)點(diǎn),不需要用父節(jié)點(diǎn)比較大小
{
//結(jié)束條件
if (root == nullptr)
{
return false;
}
//往左樹找
if (root->_key > key)
{
return _EraseR(root->_left, key);
}
//往右樹找
else if (root->_key < key)
{
return _EraseR(root->_right, key);
}
else//找到,開始刪除
{
Node* del = root;
//待刪除節(jié)點(diǎn)的左子樹為空 ,即一個(gè)孩子的情況
if (root->_left == nullptr)
{
root = root->_right;
}
//待刪除節(jié)點(diǎn)的右子樹為空 ,即一個(gè)孩子的情況
else if (root->_right == nullptr)
{
root = root->_left;
}
//待刪除的節(jié)點(diǎn)的左右孩子都不為空 (替換法:左子樹的最大節(jié)點(diǎn)即最右節(jié)點(diǎn),或者右子樹的最小節(jié)點(diǎn)即最左節(jié)點(diǎn),并且將替換的節(jié)點(diǎn)刪除)
else
{
//找左子樹最大節(jié)點(diǎn)
Node* leftMax = root->_left;
//一直往左邊找,直到找到左子樹最大節(jié)點(diǎn)
while (root->_left)
{
root = root->_left;
}
//將左子樹最大節(jié)點(diǎn)與被刪除節(jié)點(diǎn)替換
swap(leftMax->_key, root->_key);
return _EraseR(root, key);
}
delete del;//?
return true;
}
}
Find
循環(huán)
bool Find(const K & key)
{
Node* cur = _root;
while (cur)
{
if (cur->_left > key)
{
cur = cur->_left;
}
else if (cur->_left < key)
{
cur = cur->_right;
}
else
{
return false;
}
return true;
}
}
遞歸
bool FindR(Node* _root, const K& key)//遞歸版本
{
return _FindR(_root, key);
}
private:
bool _FindR(Node* root, const K& key)
{
//結(jié)束條件
if (root == nullptr)
{
return false;
}
if (root->_key > key)
{
return _FindR(root->_left, key);
}
else if (root->_key < key)
{
return _FindR(root->_right, key);
}
else
{
return true;
}
}
二叉搜索樹的應(yīng)用
K模型
K模型,即只有key作為關(guān)鍵碼,結(jié)構(gòu)中只需存儲(chǔ)key即可,關(guān)鍵碼即為需要搜索到的值。
比如:給定一個(gè)單詞,判斷該單詞是否拼寫正確。具體方式如下:
void TestBSTree1()
{
BSTree<string, string > dict;
dict.InsertR("insert", "插入");
dict.InsertR("sort", "排序");
dict.InsertR("right", "右邊");
dict.InsertR("date", "日期");
string str;
while (cin>>str)
{
auto * ret = dict.FindR(str);
//auto ret = dict.FindR(str);
if (ret)
{
cout << ret->_value << endl;
}
else
{
cout << "無此單詞" << endl;
}
}
}
KV模型
KV模型,對(duì)于每一個(gè)關(guān)鍵碼key,都有與之對(duì)應(yīng)的值value,即<key, value>的鍵值對(duì)。
英漢詞典就是英文與中文的對(duì)應(yīng)關(guān)系,即<word, Chinese>就構(gòu)成一種鍵值對(duì)。具體方式如下
1、以<單詞, 中文含義>為鍵值對(duì),構(gòu)建一棵二叉搜索樹。注意:二叉搜索樹需要進(jìn)行比較,鍵值對(duì)比較時(shí)只比較key。
2、查詢英文單詞時(shí),只需給出英文單詞就可以快速找到與其對(duì)應(yīng)的中文含義。文章來源:http://www.zghlxwxcb.cn/news/detail-723736.html
完整代碼
普通版本
#pragma once
template <class K>
struct BSTreeNode
{
BSTreeNode<K>* _left;
BSTreeNode<K>* _right;
K _key;
BSTreeNode(const K & key)
:_left(nullptr)
,_right(nullptr)
,_key(key)
{
}
};
template <class K>
class BSTree
{
typedef BSTreeNode<K> Node;
public:
BSTree()
:_root(nullptr)
{
}
bool Insert(const K & key )
{
//空樹
if (_root == nullptr)
{
_root = new Node(key);
return true;
}
//不是空樹
Node* parent = nullptr;//找到父節(jié)點(diǎn)
Node* cur = _root;
while (cur)
{
//比較
if (cur->_key < key)
{
//往右子樹走
parent = cur;
cur = cur->_right;
}
else if (cur->_key > key)
{
//往左子樹走
parent = cur;
cur = cur->_left;
}
else
{
return false;
}
}
//插入節(jié)點(diǎn)
cur = new Node(key);
//不知道parent在那一邊,需要進(jìn)一步判斷
if (parent->_key > key)
{
//parent在左邊
parent->_left = cur;
}
else if (parent->_key < key)
{
//parent在右邊
parent->_right = cur;
}
else
{
return false;
}
return true;
}
bool Find(const K & key)
{
Node* cur = _root;
while (cur)
{
if (cur->_left > key)
{
cur = cur->_left;
}
else if (cur->_left < key)
{
cur = cur->_right;
}
else
{
return false;
}
return true;
}
}
bool Erase(const K& key)
{
Node* parent = nullptr;//待刪除節(jié)點(diǎn)的父節(jié)點(diǎn)
Node* cur = _root;//待刪除的節(jié)點(diǎn)
//不是空樹
while (cur)
{
//往左邊走
if (cur->_key > key)
{
parent = cur;
cur = cur->_left;
}
//往右邊走
else if (cur->_key < key)
{
parent = cur;
cur = cur->_right;
}
//找到待刪除的節(jié)點(diǎn)
else
{
//待刪除節(jié)點(diǎn)的左子樹為空 ,即一個(gè)孩子的情況
if (cur->_left == nullptr)
{
//待刪除節(jié)點(diǎn)是根節(jié)點(diǎn)
if (cur == _root)
{
//將根節(jié)點(diǎn)改為待刪除節(jié)點(diǎn)的右孩子
_root = cur->_right;
}
//待刪除節(jié)點(diǎn)不是根節(jié)點(diǎn),并且此時(shí)parent不為nullptr
else
{
if (parent->_right == cur)
{
parent->_right = cur->_right;
}
else//parent->_left ==cur
{
parent->_left = cur->_right;
}
}
}
//待刪除節(jié)點(diǎn)的右子樹為空 ,即一個(gè)孩子的情況
else if (cur->_right == nullptr)
{
//待刪除節(jié)點(diǎn)是根節(jié)點(diǎn)
if (cur == _root)
{
//將根節(jié)點(diǎn)改為待刪除節(jié)點(diǎn)的左孩子
_root = cur->_left;
}
//待刪除節(jié)點(diǎn)不是根節(jié)點(diǎn),并且此時(shí)parent不為nullptr
else
{
if (parent->_right == cur)
{
parent->_right = cur->_left;
}
else//parent->_left==cur
{
parent->_left = cur->_left;
}
}
}
else //待刪除的節(jié)點(diǎn)的左右孩子都不為空 (替換法:左子樹的最大節(jié)點(diǎn)即最右節(jié)點(diǎn),或者右子樹的最小節(jié)點(diǎn)即最左節(jié)點(diǎn),并且將替換的節(jié)點(diǎn)刪除)
{
//替換法
//找替代節(jié)點(diǎn)
Node* parent = cur;
//找左子樹的最大節(jié)點(diǎn)
Node* leftMax = cur->_left;
while (leftMax->_right)
{
parent = leftMax; //記錄leftMax的父節(jié)點(diǎn),防止刪除leftMax時(shí)找不到該節(jié)點(diǎn)位置
//一直往右子樹找
leftMax = leftMax->_right;
}
//左子樹的最大節(jié)點(diǎn)和待刪除節(jié)點(diǎn)替換
swap(cur->_key, leftMax->_key);
//重新改變鏈接關(guān)系
//特殊情況
if (parent->_left == leftMax)
{
parent->_left = leftMax->_left;
}
else//普通情況
{
parent->_right = leftMax->_left;
//parent->_right =nullptr;
}
cur = leftMax;
}
//刪除左子樹的最大節(jié)點(diǎn)
delete cur;
return true;
}
}
return false;
}
//中序遍歷
void InOrder()
{
_InOrder(_root);
cout << endl;
}
void _InOrder(Node *root )
{
if (root == nullptr)
{
return;
}
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
private:
Node* _root;
};
void TestBSTree1()
{
int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
BSTree<int> t;
for (auto e : a)
{
t.Insert(e);
}
t.InOrder();
t.Erase(4);
t.InOrder();
t.Erase(6);
t.InOrder();
t.Erase(7);
t.InOrder();
t.Erase(3);
t.InOrder();
for (auto e : a)
{
t.Erase(e);
}
t.InOrder();
}
遞歸版本
#pragma once
#include<string>
using namespace std;
namespace key
{
template <class K>
struct BSTreeNode
{
BSTreeNode<K>* _left;
BSTreeNode<K>* _right;
K _key;
BSTreeNode(const K& key)
:_left(nullptr)
, _right(nullptr)
, _key(key)
{
}
};
template <class K>
class BSTree
{
public:
typedef BSTreeNode<K> Node;
public:
BSTree()
:_root(nullptr)
{
}
~BSTree()
{
Destroy(_root);
}
//拷貝構(gòu)造
BSTree(const BSTree<K>& t)
//BSTree( BSTree<K> *this , const BSTree<K> & t)
//t1 =t
{
_root = Copy(t._root);
}
//賦值重載
BSTree<K>& operator= (BSTree<K>& t)
//t1 = t
{
swap(_root, t._root);
return *this;
}
bool EraseR(Node* _root, const K& key)//遞歸版本
{
return _EraseR(_root, key);
}
bool InsertR(const K& key)//遞歸版本
{
return _InsertR(_root, key);
}
bool FindR(Node* _root, const K& key)//遞歸版本
{
return _FindR(_root, key);
}
private:
Node* Copy(Node* root)
{
if (root == nullptr)
{
return nullptr;
}
Node* copyNode = new Node(root->_key);
//遞歸
copyNode->_left = Copy(root->_left);
copyNode->_right = Copy(root->_right);
return copyNode;
}
void Destroy(Node*& root) //引用的目的:將每個(gè)節(jié)點(diǎn)釋放后同時(shí)置空
{
//后序遍歷
if (root == nullptr)
{
return;
}
Destroy(root->_left);
Destroy(root->_right);
delete root;
root = nullptr;
}
bool _InsertR(Node*& root, const K& key) //引用的目的:不用找父節(jié)點(diǎn),不需要用父節(jié)點(diǎn)比較大小
{
//結(jié)束條件
if (root == nullptr)
{
root = new Node(key);
return true;
}
//往左子樹走
if (root->_key > key)
{
return _InsertR(root->_left, key);
}
//往右子樹走
else if (root->_key < key)
{
return _InsertR(root->_right, key);
}
else
{
return false;
}
}
bool _EraseR(Node*& root, const K& key)//引用的目的:不用找父節(jié)點(diǎn),不需要用父節(jié)點(diǎn)比較大小
{
//結(jié)束條件
if (root == nullptr)
{
return false;
}
//往左樹找
if (root->_key > key)
{
return _EraseR(root->_left, key);
}
//往右樹找
else if (root->_key < key)
{
return _EraseR(root->_right, key);
}
else//找到,開始刪除
{
Node* del = root;
//待刪除節(jié)點(diǎn)的左子樹為空 ,即一個(gè)孩子的情況
if (root->_left == nullptr)
{
root = root->_right;
}
//待刪除節(jié)點(diǎn)的右子樹為空 ,即一個(gè)孩子的情況
else if (root->_right == nullptr)
{
root = root->_left;
}
//待刪除的節(jié)點(diǎn)的左右孩子都不為空 (替換法:左子樹的最大節(jié)點(diǎn)即最右節(jié)點(diǎn),或者右子樹的最小節(jié)點(diǎn)即最左節(jié)點(diǎn),并且將替換的節(jié)點(diǎn)刪除)
else
{
//找左子樹最大節(jié)點(diǎn)
Node* leftMax = root->_left;
//一直往左邊找,直到找到左子樹最大節(jié)點(diǎn)
while (root->_left)
{
root = root->_left;
}
//將左子樹最大節(jié)點(diǎn)與被刪除節(jié)點(diǎn)替換
swap(leftMax->_key, root->_key);
return _EraseR(root, key);
}
delete del;//?
return true;
}
}
bool _FindR(Node* root, const K& key)
{
//結(jié)束條件
if (root == nullptr)
{
return false;
}
if (root->_key > key)
{
return _FindR(root->_left, key);
}
else if (root->_key < key)
{
return _FindR(root->_right, key);
}
else
{
return true;
}
}
public:
//中序遍歷
void InOrder()
{
_InOrder(_root);
cout << endl;
}
void _InOrder(Node* root)
{
if (root == nullptr)
{
return;
}
_InOrder(root->_left);
cout << root->_key << " ";
_InOrder(root->_right);
}
public:
Node* _root;
};
void TestBSTree1()
{
int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
BSTree<int> t;
for (auto e : a)
{
t.InsertR(e);
}
t.InOrder();
//沒有引用,釋放了,只是指針沒有置空,尤其是根節(jié)點(diǎn)_root,我們還能通過他找到
/*t.Destroy(t._root);*/
t.EraseR(t._root, 4);
t.InOrder();
t.EraseR(t._root, 6);
t.InOrder();
t.EraseR(t._root, 7);
t.InOrder();
t.EraseR(t._root, 3);
t.InOrder();
for (auto e : a)
{
t.EraseR(t._root, e);
}
t.InOrder();
}
void TestBSTree2()
{
int a[] = { 8, 3, 1, 10, 6, 4, 7, 14, 13 };
BSTree<int> t;
for (auto e : a)
{
t.InsertR(e);
}
t.InOrder();
BSTree<int> t1(t);
t.InOrder();
t1.InOrder();
}
}
namespace key_value
{
template<class K, class V>
struct BSTreeNode
{
BSTreeNode<K, V>* _left;
BSTreeNode<K, V>* _right;
K _key;
V _value;
BSTreeNode(const K& key, const V& value)
:_left(nullptr)
, _right(nullptr)
, _key(key)
, _value(value)
{}
};
template<class K, class V>
class BSTree
{
public:
typedef BSTreeNode<K, V> Node;
public:
BSTree()
:_root(nullptr)
{}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
Node* FindR(const K& key)
{
return _FindR(_root, key);
}
bool InsertR(const K& key, const V& value)
{
return _InsertR(_root, key, value);
}
bool EraseR(const K& key)
{
return _EraseR(_root, key);
}
private:
bool _EraseR(Node*& root, const K& key)
{
if (root == nullptr)
return false;
if (root->_key < key)
{
return _EraseR(root->_right, key);
}
else if (root->_key > key)
{
return _EraseR(root->_left, key);
}
else
{
Node* del = root;
// 1、左為空
// 2、右為空
// 3、左右都不為空
if (root->_left == nullptr)
{
root = root->_right;
}
else if (root->_right == nullptr)
{
root = root->_left;
}
else
{
Node* leftMax = root->_left;
while (leftMax->_right)
{
leftMax = leftMax->_right;
}
swap(root->_key, leftMax->_key);
return _EraseR(root->_left, key);
}
delete del;
return true;
}
}
bool _InsertR(Node*& root, const K& key, const V& value)
{
if (root == nullptr)
{
root = new Node(key, value);
return true;
}
if (root->_key < key)
{
return _InsertR(root->_right, key, value);
}
else if (root->_key > key)
{
return _InsertR(root->_left, key, value);
}
else
{
return false;
}
}
Node* _FindR(Node* root, const K& key)
{
if (root == nullptr)
return nullptr;
if (root->_key < key)
{
return _FindR(root->_right, key);
}
else if (root->_key > key)
{
return _FindR(root->_left, key);
}
else
{
return root;
}
}
void _InOrder(Node* root)
{
if (root == NULL)
{
return;
}
_InOrder(root->_left);
cout << root->_key << ":" << root->_value << endl;
_InOrder(root->_right);
}
private:
Node* _root;
};
void TestBSTree1()
{
BSTree<string, string > dict;
dict.InsertR("insert", "插入");
dict.InsertR("sort", "排序");
dict.InsertR("right", "右邊");
dict.InsertR("date", "日期");
string str;
while (cin>>str)
{
auto * ret = dict.FindR(str);
//auto ret = dict.FindR(str);
if (ret)
{
cout << ret->_value << endl;
}
else
{
cout << "無此單詞" << endl;
}
}
}
void TestBSTree2()
{
string arr[] = {"西瓜", "西瓜", "蘋果", "西瓜", "蘋果", "蘋果", "西瓜", "蘋果", "香蕉", "蘋果", "香蕉" };
BSTree<string, int > countTree;
for (auto &str : arr)
{
auto ret = countTree.FindR(str);
if (ret == nullptr)
{
countTree.InsertR(str,1);
}
else
{
ret->_value++;
}
}
countTree.InOrder();
}
}
如果你覺得這篇文章對(duì)你有幫助,不妨動(dòng)動(dòng)手指給點(diǎn)贊收藏加轉(zhuǎn)發(fā),給鄃鱈一個(gè)大大的關(guān)注你們的每一次支持都將轉(zhuǎn)化為我前進(jìn)的動(dòng)力?。?!文章來源地址http://www.zghlxwxcb.cn/news/detail-723736.html
到了這里,關(guān)于搜索二叉樹【C++】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!