最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++二叉搜索樹圖片及代碼詳解

 更新時(shí)間:2025年11月05日 09:16:00   作者:祁同偉.  
在C++編程中二叉堆和二叉搜索樹是兩種常用的數(shù)據(jù)結(jié)構(gòu),它們具有相似之處,但是也有著不同點(diǎn),這篇文章主要介紹了C++二叉搜索樹圖片及代碼詳解的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

一. 概念

又稱二叉排序樹、二叉查找樹

性質(zhì)、判定:
        1. 若它的左子樹不為空,則左子樹上所有節(jié)點(diǎn)的值都小于根節(jié)點(diǎn)的值
        2. 若它的右子樹不為空,則右子樹上所有節(jié)點(diǎn)的值都大于根節(jié)點(diǎn)的值
        3. 它的左右子樹都是二叉搜索樹

二. 實(shí)現(xiàn)

BinarySearchTree.h

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) {}
	bool Find(const K& key) {}
	bool Erase(const K& key) {}
	void InOrder() {}

private:
	void _InOrder(Node* root) {}

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();
}

1. 查找

從根開始比較,查找,比根大則往右邊走查找,比根小則往左邊走查找

最多找高度次:O(N)

紅黑樹、AVL樹:O(logN)

bool Find(const K& key)
{
    Node* cur = _root;
    while (cur)
    {
        if (cur->_key < key)
        {
            cur = cur->_right;
        }
        else if (cur->_key > key)
        {
            cur = cur->_left;
        }
        else
        {
            return true;
        }
    }

    return false;
}

2. 插入

樹為空,則直接新增節(jié)點(diǎn),賦值給 root 指針

樹不空,按二叉搜索樹性質(zhì)查找插入位置,插入新節(jié)點(diǎn)

bool Insert(const K& key)
{
    if (_root == nullptr)
    {
        _root = new Node(key);
        return true;
    }

    Node* parent = nullptr;
    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;
        }
    }

    cur = new Node(key);
    if (parent->_key < key)
    {
        parent->_right = cur;
    }
    else
    {
        parent->_left = cur;
    }
    return true;
}

3. 中序遍歷

中序遍歷(左子樹、根、右子樹)二叉搜索樹的結(jié)果是排序的結(jié)果

void InOrder(Node* root)
{
	if (root == nullptr)
	{
		return;
	}

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

有問題,我們?cè)谕饷嬗脤?duì)象調(diào)用中序遍歷要傳私有成員變量 _root,但是私有我們不能在類外面用

BSTree<int> t;
t.InOrder();

可以這樣解決:

void InOrder()
{
    _InOrder(_root);
    cout << endl;
}

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

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

4. 刪除

要?jiǎng)h的節(jié)點(diǎn)有3種情況:

1. 沒有孩子:托孤

2. 有1個(gè)孩子:托孤

3. 有2個(gè)孩子:和左子樹的最大節(jié)點(diǎn)(左子樹的最右節(jié)點(diǎn)) 右子樹的最小節(jié)點(diǎn)(右子樹的最左節(jié)點(diǎn)) 替換

	bool Erase(const K& key)
	{
		Node* parent = nullptr;
		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 // 樹中找到了要?jiǎng)h除的節(jié)點(diǎn)cur
			{
                // ......
				delete cur;
				return true;
			}
		}

		return false;
	}

cur 左為空(也解決了沒有孩子,左右都為空):

else // 樹中找到了要?jiǎng)h除的節(jié)點(diǎn)cur
{
    // cur左為空
    if (cur->_left == nullptr)
    {
        if (parent->_right == cur)
        {
            parent->_right = cur->_right;
        }
        else
        {
            parent->_left = cur->_right;
        }
    }
    
    // ......
    delete cur;
    return true;
}

但有這種特殊情況:

else // 樹中找到了要?jiǎng)h除的節(jié)點(diǎn)cur
{
    // cur左為空
    if (cur->_left == nullptr)
    {
        if (cur == _root)
        {
            _root = cur->_right;
        }
        else
        {
            if (parent->_right == cur)
            {
                parent->_right = cur->_right;
            }
            else
            {
                parent->_left = cur->_right;
            }
        }
    }
    
    // ......
    delete cur;
    return true;
}

cur 右為空:同理

else // 樹中找到了要?jiǎng)h除的節(jié)點(diǎn)cur
{
    // cur左為空
    if (cur->_left == nullptr) { }
    // cur右為空
    else if (cur->_right == nullptr)
    {
        if (cur == _root)
        {
            _root = cur->_left;
        }
        else
        {
            if (parent->_right == cur)
            {
                parent->_right = cur->_left;
            }
            else // parent->_left == cur
            {
                parent->_left = cur->_left;
            }
        }
    }
    
    // ......
    delete cur;
    return true;
}

cur 左右都不為空:替換 以左子樹的最大節(jié)點(diǎn)(左子樹的最右節(jié)點(diǎn))為例

注意:leftMax 是左子樹的最右節(jié)點(diǎn),leftMax 這個(gè)節(jié)點(diǎn)一定不會(huì)有右子樹,可能有左子樹

注意:

        這里是左右都不為空的情況,而且我們要去左子樹找最右節(jié)點(diǎn),所以 leftMax 可直接定義為 cur->_left;parent 可直接定義為 cur

        如果 leftMax 定義為 cur,parent 定義為 nullptr,例3會(huì)坑

注意:替換后要通過找到父親直接刪(一定可以直接刪,因?yàn)?leftMax 右一定為空)。不能遞歸刪(7 < 8,在右子樹找,找不到,刪不了)。因?yàn)樗阉鳂涞慕Y(jié)構(gòu)變了,而且無法傳根,無法控制;進(jìn)而導(dǎo)致不滿足二叉搜索樹的性質(zhì)

else // 樹中找到了要?jiǎng)h除的節(jié)點(diǎn)cur
{
    // cur左為空
    if (cur->_left == nullptr) { }
    // cur右為空
    else if (cur->_right == nullptr) { }
    // cur左右都不為空
    else
    {
        // 找替代節(jié)點(diǎn)
        Node* parent = cur;
        Node* leftMax = cur->_left;
        while (leftMax->_right)
        {
            parent = leftMax;
            leftMax = leftMax->_right;
        }

        swap(cur->_key, leftMax->_key);

        if (parent->_left == leftMax)
        {
            parent->_left = leftMax->_left;
        }
        else // parent->_right == leftMax
        {
            parent->_right = leftMax->_left;
        }

        cur = leftMax;
    }
    
    delete cur;
    return true;
}

三. 遞歸版實(shí)現(xiàn)

C++里,凡是樹形結(jié)構(gòu)遞歸,都要單獨(dú)寫子函數(shù)。因?yàn)檫f歸是子問題,要控制子樹

BinarySearchTree.h

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)
	{ }

	void InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}

	bool FindR(const K& key)
	{
		return _FindR(_root, key);
	}

	bool InsertR(const K& key)
	{
		return _InsertR(_root, key);
	}

	bool EraseR(const K& key)
	{
		return _EraseR(_root, key);
	}

private:
	bool _FindR(Node* root, const K& key) {}
	bool _InsertR(Node*& root, const K& key) {}
    bool _EraseR(Node*& root, const K& key) {}
	void _InOrder(Node* root) {}

private:
	Node* _root;
};

1. 查找

比根大,在右子樹找;比根小,在左子樹找;到空還沒找到,則不存在

bool FindR(const K& key)
{
    return _FindR(_root, key);
}

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

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

2. 插入

插入的值 < 根:往左子樹去插入
插入的值 > 根:往右子樹去插入
插入的值 == 根:插入失敗
走到空的地方就可以插入

怎么插入?new Node(key),但還要找父親,怎么解決?加引用成為 Node*& root

這里指針的作用:鏈接樹

這里引用的作用:下一層改變影響上一層

bool InsertR(const K& key)
{
    return _InsertR(_root, key);
}

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

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

如果是空樹,root 是 _root 的別名,new 的第一個(gè)節(jié)點(diǎn)剛好給 _root

如果不是空樹,層層往下遞歸,前面的引用不起作用,每一層(每一個(gè)棧幀都有一個(gè)引用

6 是對(duì)象,把左指針這個(gè)成員傳給下一層,下一層的 root 是 6 的左指針的別名(引用此時(shí)不發(fā)揮作用)

5 > 4,把 4 的右指針往下傳,root 4 的右指針的別名

4 的右指針為空 ==> 插入

new節(jié)點(diǎn),給 root,對(duì) root 修改,就是對(duì) 4 的右指針修改

這一句賦值,直接就鏈接上了,不用找父親,不用比較大小

3. 刪除

先找有沒有要?jiǎng)h的節(jié)點(diǎn),找到了就刪,同樣分3種情況:左為空、右為空、左右都為空

bool EraseR(const K& key)
{
    return _EraseR(_root, key);
}

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 // 找到了,準(zhǔn)備刪
    {
        Node* del = root;
        
        if (root->_left == nullptr) // 1.左為空
        {
            root = root->_right;
        }
        else if (root->_right == nullptr) // 2.右為空
        {
            root = root->_left;
        }
        else // 3. 左右都不為空
        { }

        delete del;
        return true;
    }
}

3 < 6,3 的右指針往下傳,root 是 3 的右指針的別名

此時(shí) root 是 6,找到了,開始刪:root 左為空,把 root(3的右指針)賦值為 root 的右指針

root 的右指針指向 7 ==> 3 的右指針指向 7,完成了鏈接關(guān)系

root 是 _root 的別名,上來就找到了,開始刪:

root 不為空,root = root->_right 就是 _root = _root->_right;

左右都為空:找替代節(jié)點(diǎn)(以找左樹的最右節(jié)點(diǎn)為例,最右節(jié)點(diǎn)的右一定為空)

以剛開始就找到要?jiǎng)h的 8 為例:

        轉(zhuǎn)化為刪紅圈的節(jié)點(diǎn)。非遞歸實(shí)現(xiàn)一定可以找父親,直接刪;不能遞歸刪

我們現(xiàn)在有了引用,root 是 _root 的別名

但在 root 當(dāng)前位置發(fā)揮不了作用,因?yàn)椴恍枰?_root,所以不能直接在最大的樹刪除

可以轉(zhuǎn)化為在藍(lán)圈的樹中刪,遞歸往下走,一定是右為空的情況。那時(shí),root 是 6 的右指針的別名

走這個(gè)情形:

else // 3. 左右都不為空
{
    Node* leftMax = root->_left;
    while (leftMax->_right)
    {
        leftMax = leftMax->_right;
    }

    swap(root->_key, leftMax->_key);

    return _EraseR(root->_left, key);
}

這種方法在替換后,會(huì)在左子樹再找一遍要?jiǎng)h除的節(jié)點(diǎn),但代價(jià)不大

第11行遞歸進(jìn)去之后,不會(huì)再次走這個(gè)左右都不為空的 else

4. 析構(gòu)、拷貝、賦值

析構(gòu):析構(gòu)也得寫子函數(shù),因?yàn)橐f歸,析構(gòu)函數(shù)都沒有參數(shù)

        二叉樹:用后序遍歷刪除,循環(huán)不好用

拷貝:不能調(diào) Insert,會(huì)改變樹的形狀

        走前序遍例賦值

默認(rèn)的拷貝構(gòu)造是淺拷貝,會(huì)出錯(cuò),要自己實(shí)現(xiàn)深拷貝

賦值:現(xiàn)代寫法

BSTree(const BSTree<K>& t)
{
    _root =  Copy(t._root);
}

BSTree<K>& operator=(BSTree<K> t)
{
    swap(_root, t._root);
    return *this;
}

~BSTree()
{
    Destroy(_root);
}

void Destroy(Node*& root)
{
    if (root == nullptr)
        return;

    Destroy(root->_left);
    Destroy(root->_right);
    delete root;
    root = nullptr; // 這就是傳引用的原因
}

Node* Copy(Node* root)
{
    if (root == nullptr)
        return nullptr;

    Node* copyroot = new Node(root->_key);
    copyroot->_left = Copy(root->_left);
    copyroot->_right = Copy(root->_right);
    return copyroot;
}

非遞歸+遞歸整體代碼

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)
	{ }

	BSTree(const BSTree<K>& t)
	{
		_root =  Copy(t._root);
	}

	BSTree<K>& operator=( BSTree<K> t)
	{
		swap(_root, t._root);
		return *this;
	}

	~BSTree()
	{
		Destroy(_root);
	}

	bool Insert(const K& key)
	{
		if (_root == nullptr)
		{
			_root = new Node(key);
			return true;
		}

		Node* parent = nullptr;
		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;
			}
		}

		cur = new Node(key);
		if (parent->_key < key)
		{
			parent->_right = cur;
		}
		else
		{
			parent->_left = cur;
		}
		return true;
	}

	bool Find(const K& key)
	{
		Node* cur = _root;
		while (cur)
		{
			if (cur->_key < key)
			{
				cur = cur->_right;
			}
			else if (cur->_key > key)
			{
				cur = cur->_left;
			}
			else
			{
				return true;
			}
		}

		return false;
	}

	bool Erase(const K& key)
	{
		Node* parent = nullptr;
		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 // 樹中找到了要?jiǎng)h除的節(jié)點(diǎn)cur
			{
				// cur左為空
				if (cur->_left == nullptr)
				{
					if (cur == _root)
					{
						_root = cur->_right;
					}
					else
					{
						if (parent->_right == cur)
						{
							parent->_right = cur->_right;
						}
						else // parent->_left == cur
						{
							parent->_left = cur->_right;
						}
					}
				}
				// cur右為空
				else if (cur->_right == nullptr)
				{
					if (cur == _root)
					{
						_root = cur->_left;
					}
					else
					{
						if (parent->_right == cur)
						{
							parent->_right = cur->_left;
						}
						else // parent->_left == cur
						{
							parent->_left = cur->_left;
						}
					}
				}
				// cur左右都不為空 
				else
				{
					// 找替代節(jié)點(diǎn)
					Node* parent = cur;
					Node* leftMax = cur->_left;
					while (leftMax->_right)
					{
						parent = leftMax;
						leftMax = leftMax->_right;
					}

					swap(cur->_key, leftMax->_key);

					if (parent->_left == leftMax)
					{
						parent->_left = leftMax->_left;
					}
					else // parent->_right == leftMax
					{
						parent->_right = leftMax->_left;
					}

					cur = leftMax;
				}

				delete cur;
				return true;
			}
		}

		return false;
	}

	void InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}

	bool FindR(const K& key)
	{
		return _FindR(_root, key);
	}

	bool InsertR(const K& key)
	{
		return _InsertR(_root, key);
	}

	bool EraseR(const K& key)
	{
		return _EraseR(_root, key);
	}

private:
	void Destroy(Node*& root)
	{
		if (root == nullptr)
			return;

		Destroy(root->_left);
		Destroy(root->_right);
		delete root;
		root = nullptr; // 這就是傳引用的原因
	}

	Node* Copy(Node* root)
	{
		if (root == nullptr)
			return nullptr;

		Node* copyroot = new Node(root->_key);
		copyroot->_left = Copy(root->_left);
		copyroot->_right = Copy(root->_right);
		return copyroot;
	}

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

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

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

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

	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 // 找到了,準(zhǔn)備刪
		{
			Node* del = root;
			
			if (root->_left == nullptr) // 1.左為空
			{
				root = root->_right;
			}
			else if (root->_right == nullptr) // 2.右為空
			{
				root = root->_left;
			}
			else // 3. 左右都不為空
			{
				Node* leftMax = root->_left;
				while (leftMax->_right)
				{
					leftMax = leftMax->_right;
				}

				swap(root->_key, leftMax->_key);

				return _EraseR(root->_left, key);
			}

			delete del;
			return true;
		}
	}

	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.InsertR(e);
	}

	t.InOrder();

	t.EraseR(4);
	t.InOrder();

	t.EraseR(6);
	t.InOrder();

	t.EraseR(7);
	t.InOrder();

	t.EraseR(3);
	t.InOrder();

	for (auto e : a)
	{
		t.EraseR(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);
	}

	BSTree<int> t1(t);

	t.InOrder();
	t1.InOrder();
}

四. 應(yīng)用模型

1. key 的搜索模型

快速判斷在不在的場(chǎng)景

門禁系統(tǒng)、小區(qū)車輛出入系統(tǒng) ……

2. key_value 的搜索模型

通過一個(gè)值找另一個(gè)值

商場(chǎng)的車輛出入系統(tǒng)、高鐵實(shí)名制車票系統(tǒng) ……

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
	{
		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:
		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;
			}
		}

		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;
			}
		}

		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 // 找到了,準(zhǔn)備刪
			{
				Node* del = root;

				if (root->_left == nullptr) // 1.左為空
				{
					root = root->_right;
				}
				else if (root->_right == nullptr) // 2.右為空
				{
					root = root->_left;
				}
				else // 3. 左右都不為空
				{
					Node* leftMax = root->_left;
					while (leftMax->_right)
					{
						leftMax = leftMax->_right;
					}

					swap(root->_key, leftMax->_key);

					return _EraseR(root->_left, key);
				}

				delete del;
				return true;
			}
		}

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

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

	private:
		Node* _root;
	};
}

拼寫檢查:讀取詞庫放到一顆搜索樹;讀取單詞,看在不在樹中,不在則拼寫錯(cuò)誤

void TestBSTree1()
{
    BSTree<string, string> dict;
    dict.InsertR("hello", "你好");
    dict.InsertR("tree", "樹");
    dict.InsertR("apple", "蘋果");
    dict.InsertR("day", "天");

    string str;
    while (cin >> str)
    {
        BSTreeNode<string, string>* ret = dict.FindR(str);
        if (ret != nullptr)
        {
            cout << ret->_value << endl;
        }
        else
        {
            cout << "沒有此單詞" << endl;
        }
    }
}

統(tǒng)計(jì)出現(xiàn)次數(shù)

void TestBSTree2()
{
    string arr[] = { "蘋果", "西瓜", "蘋果", "西瓜", "蘋果",
        "蘋果", "西瓜", "蘋果", "香蕉", "蘋果", "香蕉" };
    BSTree<string, int> countTree;
    for (auto& str : arr)
    {
        BSTreeNode<string, int>* ret = countTree.FindR(str);
        if (ret == nullptr)
        {
            countTree.InsertR(str, 1);
        }
        else
        {
            ret->_value++;
        }
    }

    countTree.InOrder();
}

總結(jié)

到此這篇關(guān)于C++二叉搜索樹詳解的文章就介紹到這了,更多相關(guān)C++二叉搜索樹內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis的新特性懶惰刪除Lazy Free詳解

    Redis的新特性懶惰刪除Lazy Free詳解

    這篇文章主要介紹了Redis的新特性懶惰刪除Lazy Free詳解,Redis4.0新增了非常實(shí)用的lazy free特性,從根本上解決Big Key(主要指定元素較多集合類型Key)刪除的風(fēng)險(xiǎn),需要的朋友可以參考下
    2019-06-06
  • Ubuntu20.04安裝使用jsoncpp、json-c庫的方法實(shí)例

    Ubuntu20.04安裝使用jsoncpp、json-c庫的方法實(shí)例

    這篇文章主要給大家介紹了關(guān)于Ubuntu20.04安裝使用jsoncpp、json-c庫的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作就有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-04-04
  • C++實(shí)現(xiàn)線性表鏈?zhǔn)酱鎯?chǔ)(單鏈)

    C++實(shí)現(xiàn)線性表鏈?zhǔn)酱鎯?chǔ)(單鏈)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)線性表鏈?zhǔn)酱鎯?chǔ),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • C語言快速排序與二分查找算法示例

    C語言快速排序與二分查找算法示例

    這篇文章主要介紹了C語言快速排序與二分查找算法,涉及C語言隨機(jī)數(shù)生成、快速排序及二分查找等算法相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2018-01-01
  • C語言逗號(hào)運(yùn)算符和逗號(hào)表達(dá)式的使用小結(jié)

    C語言逗號(hào)運(yùn)算符和逗號(hào)表達(dá)式的使用小結(jié)

    本文詳細(xì)介紹了C語言中的逗號(hào)運(yùn)算符和逗號(hào)表達(dá)式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-11-11
  • c++臨時(shí)對(duì)象導(dǎo)致的生命周期問題

    c++臨時(shí)對(duì)象導(dǎo)致的生命周期問題

    對(duì)象的生命周期是c++中非常重要的概念,它直接決定了你的程序是否正確以及是否存在安全問題,這篇文章主要介紹了c++臨時(shí)對(duì)象導(dǎo)致的生命周期問題 ,需要的朋友可以參考下
    2024-07-07
  • 詳解C語言隨機(jī)數(shù)設(shè)置的三種方式(保姆級(jí)教程)

    詳解C語言隨機(jī)數(shù)設(shè)置的三種方式(保姆級(jí)教程)

    本篇文章將為大家介紹在C語言中設(shè)置隨機(jī)數(shù)的三大方法的使用,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語言有一定的幫助,需要的可以參考一下
    2022-11-11
  • C++中的數(shù)據(jù)內(nèi)存分布原理

    C++中的數(shù)據(jù)內(nèi)存分布原理

    這篇文章主要介紹了C++中的數(shù)據(jù)內(nèi)存分布,主要從動(dòng)態(tài)內(nèi)存管理方式,內(nèi)存泄漏等方面介紹的,文中也有相關(guān)的示例代碼,需要的朋友可以參考下
    2023-05-05
  • 深入了解C++中常用的三個(gè)智能指針

    深入了解C++中常用的三個(gè)智能指針

    C++是一門強(qiáng)大的編程語言,但是在內(nèi)存管理方面卻存在著一些問題。手動(dòng)管理內(nèi)存不僅費(fèi)時(shí)費(fèi)力,而且容易出錯(cuò)。因此,C++中引入了智能指針這一概念,以更好地管理內(nèi)存,下面就來詳細(xì)講講C++中常用的三個(gè)智能指針吧
    2023-05-05
  • EasyC++內(nèi)部鏈接性和無鏈接性

    EasyC++內(nèi)部鏈接性和無鏈接性

    這篇文章主要介紹了EasyC++內(nèi)部鏈接性和無鏈接性,當(dāng)我們使用static關(guān)鍵字,將變量的作用于限制在整個(gè)文件時(shí),該變量的鏈接性為內(nèi)部鏈接性,然而無鏈接性的變量其實(shí)就是在代碼塊當(dāng)中使用static關(guān)鍵字創(chuàng)建的,接下來一起進(jìn)入文章了解更多內(nèi)容吧
    2021-12-12

最新評(píng)論

广平县| 新巴尔虎左旗| 长子县| 确山县| 库尔勒市| 方城县| 习水县| 新和县| 浑源县| 廊坊市| 前郭尔| 营口市| 佛学| 永安市| 高州市| 霍邱县| 庄河市| 台安县| 灵台县| 博野县| 曲阳县| 白河县| 仪陇县| 梁山县| 金川县| 邵阳县| 屏边| 白河县| 嘉兴市| 东海县| 皮山县| 娄底市| 科技| 周口市| 沙湾县| 渝中区| 肥东县| 中西区| 醴陵市| 拉孜县| 佛学|