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

C++ map與set封裝實現(xiàn)過程講解

 更新時間:2023年03月08日 10:33:42   作者:平凡的人1  
set set是一種關聯(lián)式容器,下面這篇文章主要給大家介紹了關于C++中map和set使用的相關資料,文中通過實例代碼介紹的非常詳細,對大家學習或者使用C++具有一定的參考學習價值,需要的朋友可以參考下

一、前情回顧

set 參數(shù)只有 key,但是map除了key還有value。我們還是需要KV模型的紅黑樹的:

#pragma once
#include <iostream>
#include <assert.h>
#include <time.h>
using namespace std;
enum Color
{
	RED,
	BLACK,
};
template<class K, class V >
struct RBTreeNode
{
	pair<K, V> _kv;
	RBTreeNode<K, V>* _left;
	RBTreeNode<K, V>* _right;
	RBTreeNode<K, V>* _parent;
	Color _col;
	RBTreeNode(const pair<K,V>& kv)
		:_kv(kv)
		,_left(nullptr)
		,_right(nullptr)
		,_parent(nullptr)
		,_col(RED)
	{}
};
template<class K,class V>
class RBTree
{
	typedef RBTreeNode<K, V> Node;
public:
	bool Insert(const pair<K, V>& kv)
	{
		if (_root == nullptr)
		{
			_root = new Node(kv);
			_root->_col = BLACK;
			return true;
		}
		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{
			if (cur->_kv.first < kv.first)
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (cur->_kv.first > kv.first)
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return false;
			}
		}
		cur = new Node(kv);
		cur->_col = RED;
		if (parent->_kv.first < kv.first)
		{
			parent->_right = cur;
			cur->_parent = parent;
		}
		else
		{
			parent->_left = cur;
			cur->_parent = parent;
		}
		while (parent && parent->_col == RED)
		{
			Node* grandfater = parent->_parent;
			if (parent == grandfater->_left)
			{
				Node* uncle = grandfater->_right;
				//情況一:u存在且為紅
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfater->_col = RED;
					//向上調(diào)整
					cur = grandfater;
					parent = cur->_parent;
				}
				else
				{
					//情況2
					if (cur == parent->_left)
					{
						RotateR(grandfater);
						parent->_col = BLACK;
						grandfater->_col = RED;
					}
					//情況3
					else
					{
						//       g
						//  p
						//    c 
						RotateL(parent);
						RotateR(grandfater);
						cur->_col = BLACK;
						grandfater->_col = RED;
					}
					break;
				}
			}
			else//parent==grandfater->_right
			{
				Node* uncle = grandfater->_left;
				//情況1:u存在且為紅色
				if (uncle && uncle->_col == RED)
				{
					uncle->_col = parent->_col = BLACK;
					grandfater->_col = RED;
					//向上調(diào)整
					cur = grandfater;
					parent = cur->_parent;
				}
				else
				{
					//情況2:u不存在/u存在為黑色
					//g
					//    p
					//        c
					if (cur == parent->_right)
					{
						RotateL(grandfater);
						grandfater->_col = RED;
						parent->_col = BLACK;
					}
					//情況3
					//     g
					 //         p
					 //      c
					else
					{
						RotateR(parent);
						RotateL(grandfater);
						cur->_col = BLACK;
						grandfater->_col = RED;
					}
					break;
				}
			}
		}
		//根變黑
		_root->_col = BLACK;
		return true;
	}
	void RotateL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;
		parent->_right = subRL;
		if (subRL)
			subRL->_parent = parent;
		Node* ppNode = parent->_parent;
		subR->_left = parent;
		parent->_parent = subR;
		if (ppNode == nullptr)
		{
			_root = subR;
			_root->_parent = nullptr;
		}
		else
		{
			if (ppNode->_left == parent)
			{
				ppNode->_left = subR;
			}
			else
			{
				ppNode->_right = subR;
			}
			subR->_parent = ppNode;
		}
	}
	void RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;
		parent->_left = subLR;
		if (subLR)
			subLR->_parent = parent;
		Node* ppNode = parent->_parent;
		parent->_parent = subL;
		subL->_right = parent;
		if (ppNode == nullptr)
		{
			_root = subL;
			_root->_parent = nullptr;
		}
		else
		{
			if (ppNode->_left == parent)
			{
				ppNode->_left = subL;
			}
			else
			{
				ppNode->_right = subL;
			}
			subL->_parent = ppNode;
		}
	}
	void InOrder()
	{
		_InOrder(_root);
	}
	void _InOrder(Node* root)
	{
		if (root == nullptr)
			return;
		_InOrder(root->_left);
		cout << root->_kv.first << ":" << root->_kv.second << endl;
		_InOrder(root->_right);
	}
	bool Check(Node*root,int blackNum,int ref)
	{
		if (root == nullptr)
		{
			//cout << blackNum << endl;
			if (blackNum != ref)
			{
				cout << "違反規(guī)則:本條路徑的黑色結(jié)點的數(shù)量根最左路徑不相等" << endl;
				return false;
			}
			return true;
		}
		if (root->_col == RED && root->_parent->_col == RED)
		{
			cout << "違反規(guī)則:出現(xiàn)連續(xù)的紅色結(jié)點" << endl;
			return false;
		}
		if (root->_col == BLACK)
		{
			++blackNum;
		}
		return Check(root->_left,blackNum,ref)
			&& Check(root->_right,blackNum,ref);
	}
	bool IsBalance()
	{
		if (_root == nullptr)
		{
			return true;
		}
		if (_root->_col != BLACK)
		{
			return false;
		}
		int ref = 0;
		Node* left = _root;
		while (left)
		{
			if (left->_col == BLACK)
			{
				++ref;
			}
			left = left->_left;
		}
		return Check(_root,0,ref);
	}
private:
	Node* _root = nullptr;
};

二、簡化源碼

翻開源碼一看

RBTree的結(jié)構源碼:是KV結(jié)構的紅黑樹

RBTree是通過傳入的Value的值來判斷類型,也就是一棵泛型的RBTree,通過不同的實例化,實現(xiàn)出了Map和Set:

對于map:傳key,對于set:傳pair

map的結(jié)構簡化源碼:

set的結(jié)構簡化源碼:

為了讓我們的紅黑樹能夠識別set與map我們增加一個模板參數(shù)T:

template<class K, class T>
class RBTree

對于T模板參數(shù)可能是鍵值Key,也可能是由Key和Value共同構成的鍵值對。

如果是set容器,那么它傳入底層紅黑樹的模板參數(shù)就是Key和Key:

template<class K>
class set
{
  private:
    RBTree<K,K> _t;
};

如果是map容器,傳入底層紅黑樹的模板參數(shù)就是Key和Key和value的鍵值對:

class map
{
private:
    RBTree<K, pair<const K,V>> _t;
};

通過上面,我們可以知道,對于set和map的區(qū)別:我們只要通過第二個模板參數(shù)就能進行區(qū)分,那是不是第一個模板參數(shù)就沒有意義了呢?

對于insert(const Value&v)來說,需要放入存入的值,確實是這個樣子的,插入的值是value,對于set就是key,對于map就是pair。

但是對于find(const Key&key)來說,查找的參數(shù)不是value,找的不是pair而是Key,對于map容器來說就不行了。

**紅黑樹的節(jié)點**:set容器:K和T都是鍵值Key; map容器:K是鍵值Key,T由Key和Value構成的鍵值對;但是底層紅黑樹并不知道上層容器到底是map還是set,因此紅黑樹的結(jié)點當中直接存儲T就行了,如果是set的時候,結(jié)點當中存儲的是鍵值Key;如果是map的時候,結(jié)點當中存儲的就是鍵值對,所以紅黑樹的結(jié)點定義如下,由T類型來決定紅黑樹存的是key還是pair:

template<class T>
    //三叉鏈結(jié)構
struct RBTreeNode
{
	T _data;
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;
	Color _col;
	RBTreeNode(const T& data)
		:_data(data)
		, _left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _col(RED)
	{}
};

三、仿函數(shù)

這里存在一個問題??:插入的時候data的大小如何去進行比較:我們并不知道是什么類型是key,還是pair的比較,而我們剛開始kv結(jié)構就直接用kv.first去比較了。

對于set是Key,可以比較

對于map是pair,那我們要取其中的first來比較,但是pair的大小并不是直接按照first去進行比較的,而我們只需要按照first去進行比較

由于底層的紅黑樹不知道傳的是map還是set容器,當需要進行兩個結(jié)點鍵值的比較時,底層紅黑樹傳入的仿函數(shù)來獲取鍵值Key,進行兩個結(jié)點鍵值的比較:這個時候我們就需要仿函數(shù)了,如果是set那就是用于返回T當中的鍵值Key,如果是map那就是用于返回pair的first:

仿函數(shù)/函數(shù)對象也是類,是一個類對象。仿函數(shù)要重載operator()。

namespace HWC
{
	template<class K,class V>
	class map
	{
		struct  MapKeyOfT
		{
			const K& operator()(const pair<const K, V>& kv)
			{
				return kv.first;
			}
		};
	public:
	private:
		RBTree<K, pair<const K,V>,MapKeyOfT> _t;
	};
namespace HWC
{
	template<class K>
	class set
	{
		struct SetKeyOfT
		{
			const K& operator()(const K& key)
			{
				return key;
			}
		};
	private:
		RBTree<K,K,SetKeyOfT> _t;
	};

博主畫了個圖更加容易進行比對

查找過程,此時就可以套上我們所寫的仿函數(shù)對象去進行數(shù)據(jù)的大小比較了:

        KeyOfT kot;//仿函數(shù)對象
		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{
			if (kot(cur->_data)<kot(data))
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (kot(cur->_data)>kot(data))
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return false;
			}
		}

四、迭代器

紅黑樹的正向迭代器是對結(jié)點指針進行了封裝,所以這里的正向迭代器就只有一個成員變量:結(jié)點的指針,并沒有什么其他的地方,迭代器的定義:

template<class T,class Ref,class Ptr>
struct __RBTreeIterator
{
	typedef RBTreeNode<T> Node;
	typedef __RBTreeIterator<T,Ref,Ptr> Self;
	typedef __RBTreeIterator<T, T&, T*> iterator;
	Node* _node;
	__RBTreeIterator(Node*node)
		:_node(node)
	{}
	//普通迭代器的時候,它是拷貝構造
	//const迭代器的時候,它是構造,支持用普通迭代器構造const迭代器
	__RBTreeIterator(const iterator& s)
		:_node(s._node)
	{}
}

*:解引用操作,返回對應結(jié)點數(shù)據(jù)的引用:

Ref operator*()
	{
		return _node->_data;
	}

->:成員訪問操作符,返回結(jié)點數(shù)據(jù)的引用:

Ptr operator->()
	{
		return &_node->_data;
	}

!=、==:比較簡單

  bool operator !=(const Self & s) const
	{
		return _node != s._node;
	}
	bool operator ==(const Self& s) const
	{
		return _node == s._node;
	}

這里的迭代器重點是迭代器的++:

一個結(jié)點的正向迭代器進行++操作后,根據(jù)紅黑樹中序(左、根、右)找到當前結(jié)點的下一個結(jié)點,中序的第一個節(jié)點是最左,迭代器的++怎么去找:

如果節(jié)點的右子樹不為空,++就是找右子樹的最左節(jié)點

如果節(jié)點的右子樹為空,++就是找祖先(孩子是父親的左的那個祖先)

代碼實現(xiàn):

	Self& operator++()
	{
		if (_node->_right)
		{
			Node* min = _node->_right;
			while (min->_left)
			{
				min = min->_left;
			}
			_node = min;
		}
		else
		{
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent && cur == parent->_right)
			{
				cur = cur->_parent;
				parent = parent->_parent;
			}
			_node = parent;
		}
		return *this;
	}

迭代器的--

對于–,如果是根,–就是左子樹,找到左子樹最大的那一個(最右節(jié)點)

如果節(jié)點的左子樹不為空,--找左子樹最右的節(jié)點

如果節(jié)點的左子樹為空,--找祖先(孩子是父親的右的祖先)

代碼實現(xiàn):

Self& operator--()
	{
		if (_node->_left)
		{
			Node* max = _node->_left;
			while (max->_right)
			{
				max = max->_right;
			}
			_node = max;
		}
		else
		{
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent&&cur==parent->_left)
			{
				cur = cur->_parent;
				parent = parent->_parent;
			}
			_node = parent;
		}
		return *this;
	}

不要忘記迭代器的兩個核心成員:begin()與end()

begin():返回中序(左、根、右)第一個結(jié)點的正向迭代器,即最左節(jié)點,返回的是最左節(jié)點,直接找最左節(jié)點即可

end():返回中序(左、根、右)最后一個結(jié)點下一個位置的正向迭代器,這里直接用空指針

template<class K, class T,class KeyOfT>
class RBTree
{
	typedef RBTreeNode<T> Node;
public:
	typedef __RBTreeIterator<T> iterator;
	iterator begin()
	{
		Node* left = _root;
		while (left && left->_left)
		{
			left = left->_left;
		}
		return iterator(left);
	}
	iterator end()
	{
		return iterator(nullptr);
	}
}

五、set的實現(xiàn)

通過前面底層紅黑樹的接口進行套用即可實現(xiàn)set的實現(xiàn):

值得注意的是??:typename:沒有實例化的模板,區(qū)分不了是靜態(tài)變量還是類型,typename告訴編譯器是類型

#pragma once
#include "RBTree.h"
namespace hwc
{
	template <class K>
	class set
	{
		struct SetKeyOfT
		{
			const K& operator()(const K& key)
			{
				return key;
			}
		};
	public:
        //typename:沒有實例化的模板,區(qū)分不了是靜態(tài)變量還是類型,typename告訴編譯器是類型
		typedef typename RBTree<K, K, SetKeyOfT>::const_iterator iterator;//key不可以修改
		typedef typename RBTree<K, K, SetKeyOfT>::const_iterator const_iterator;
		iterator begin() const 
		{
			return _t.begin();
		}
		iterator end() const 
		{
			return _t.end();
		}
		pair<iterator,bool> insert(const K& key)
		{
            //底層紅黑樹的iterator是普通迭代器
			pair<typename RBTree<K, K, SetKeyOfT>::iterator, bool> ret =  _t.Insert(key);
			return pair<iterator, bool>(ret.first, ret.second);//用普通迭代器構造const迭代器
		}
	private:
		RBTree<K, K,SetKeyOfT> _t;
	};
	void test_set()
	{
		int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
		set<int> s;
		for (auto e : a)
		{
			s.insert(e);
		}
		set<int>::iterator it = s.begin();
		while (it != s.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;
		for (auto e : s)
		{
			cout << e << " ";
		}
		cout << endl;
	}
}

六、map的實現(xiàn)

同樣是套用上底層紅黑樹的接口,不過map的實現(xiàn)有一個很重要的地方,那就是[]的實現(xiàn)

#pragma once
#include "RBTree.h"
namespace hwc
{
	template<class K,class V>
	class map
	{
		struct MapkeyOfT
		{
			const K& operator()(const pair<const K, V>& kv)
			{
				return kv.first;
			}
		};
	public:
		//typename:沒有實例化的模板,區(qū)分不了是靜態(tài)變量還是類型,typename告訴編譯器是類型
		typedef typename RBTree<K, pair<const K, V>, MapkeyOfT>::iterator iterator;
		typedef typename RBTree<K, pair<const K, V>, MapkeyOfT>::const_iterator 
			const_iterator;
		iterator begin()
		{
			return _t.begin();
		}
		iterator end()
		{
			return _t.end();
		}
		const_iterator begin() const
		{
			return _t.begin();
		}
		const_iterator end() const
		{
			return _t.end();
		}
		pair<iterator,bool> insert(const pair<const K, V>& kv)
		{
			return _t.Insert(kv);
		}
		V& operator[](const K& key)
		{
			pair<iterator, bool> ret = insert(make_pair(key, V()));
			return ret.first->second;
		}
	private:
		RBTree<K, pair<const K, V>, MapkeyOfT> _t;
	};
	void test_map()
	{
		int a[] = { 4, 2, 6, 1, 3, 5, 15, 7, 16, 14 };
		map<int, int> m;
		for (auto e : a)
		{
			m.insert(make_pair(e, e));
		}
		map<int, int>::iterator it = m.begin();
		while(it!=m.end())
		{
			it->second++;
			cout << it->first << ":" << it->second << endl;
			++it;
		}
		cout << endl;
		map<string, int> countMap;
		string arr[] = { "蘋果","西瓜","香蕉","蘋果"};
		for (auto& e : arr)
		{
			countMap[e]++;
		}
		for (auto& kv : countMap)
		{
			cout << kv.first << ":" << kv.second << endl;
		}
	}
}

七、紅黑樹代碼

最后,在這里送上源碼:

#pragma once
#pragma once
#include <iostream>
#include <assert.h>
#include <time.h>
using namespace std;
enum Color
{
	RED,
	BLACK,
};
template<class T>
struct RBTreeNode
{
	T _data;
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;
	Color _col;
	RBTreeNode(const T& data)
		:_data(data)
		, _left(nullptr)
		, _right(nullptr)
		, _parent(nullptr)
		, _col(RED)
	{}
};
template<class T,class Ref,class Ptr>
struct __RBTreeIterator
{
	typedef RBTreeNode<T> Node;
	typedef __RBTreeIterator<T,Ref,Ptr> Self;
	typedef __RBTreeIterator<T, T&, T*> iterator;
	Node* _node;
	__RBTreeIterator(Node*node)
		:_node(node)
	{}
	//普通迭代器的時候,它是拷貝構造
	//const迭代器的時候,它是構造,支持用普通迭代器構造const迭代器
	__RBTreeIterator(const iterator& s)
		:_node(s._node)
	{}
	Ref operator*()
	{
		return _node->_data;
	}
	Ptr operator->()
	{
		return &_node->_data;
	}
	Self& operator++()
	{
		if (_node->_right)
		{
			Node* min = _node->_right;
			while (min->_left)
			{
				min = min->_left;
			}
			_node = min;
		}
		else
		{
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent && cur == parent->_right)
			{
				cur = cur->_parent;
				parent = parent->_parent;
			}
			_node = parent;
		}
		return *this;
	}
	Self& operator--()
	{
		if (_node->_left)
		{
			Node* max = _node->_left;
			while (max->_right)
			{
				max = max->_right;
			}
			_node = max;
		}
		else
		{
			Node* cur = _node;
			Node* parent = cur->_parent;
			while (parent&&cur==parent->_left)
			{
				cur = cur->_parent;
				parent = parent->_parent;
			}
			_node = parent;
		}
		return *this;
	}
	bool operator !=(const Self & s) const
	{
		return _node != s._node;
	}
	bool operator ==(const Self& s) const
	{
		return _node == s._node;
	}
};
template<class K, class T,class KeyOfT>
class RBTree
{
	typedef RBTreeNode<T> Node;
public:
	typedef __RBTreeIterator<T,T&,T*> iterator;
	typedef __RBTreeIterator<T,const T&,const T*> const_iterator;
	const_iterator begin() const 
	{
		Node* left = _root;
		while (left && left->_left)
		{
			left = left->_left;
		}
		return const_iterator(left);
	}
	const_iterator end() const 
	{
		return const_iterator(nullptr);
	}
	iterator begin()
	{
		Node* left = _root;
		while (left && left->_left)
		{
			left = left->_left;
		}
		return iterator(left);
	}
	iterator end()
	{
		return iterator(nullptr);
	}
	pair<iterator,bool> Insert(const T& data)
	{
		if (_root == nullptr)
		{
			_root = new Node(data);
			_root->_col = BLACK;
			return make_pair(iterator(_root),true);
		}
		KeyOfT kot;
		Node* parent = nullptr;
		Node* cur = _root;
		while (cur)
		{
			if (kot(cur->_data) < kot(data))
			{
				parent = cur;
				cur = cur->_right;
			}
			else if (kot(cur->_data) > kot(data))
			{
				parent = cur;
				cur = cur->_left;
			}
			else
			{
				return make_pair(iterator(cur),false);
			}
		}
		cur = new Node(data);
		Node* newnode = cur;
		cur->_col = RED;
		if (kot(parent->_data) < kot(data))
		{
			parent->_right = cur;
			cur->_parent = parent;
		}
		else
		{
			parent->_left = cur;
			cur->_parent = parent;
		}
		while (parent && parent->_col == RED)
		{
			Node* grandfater = parent->_parent;
			if (parent == grandfater->_left)
			{
				Node* uncle = grandfater->_right;
				//情況一:u存在且為紅
				if (uncle && uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfater->_col = RED;
					//向上調(diào)整
					cur = grandfater;
					parent = cur->_parent;
				}
				else
				{
					//情況2
					if (cur == parent->_left)
					{
						RotateR(grandfater);
						parent->_col = BLACK;
						grandfater->_col = RED;
					}
					//情況3
					else
					{
						//       g
						//  p
						//    c 
						RotateL(parent);
						RotateR(grandfater);
						cur->_col = BLACK;
						grandfater->_col = RED;
					}
					break;
				}
			}
			else//parent==grandfater->_right
			{
				Node* uncle = grandfater->_left;
				//情況1:u存在且為紅色
				if (uncle && uncle->_col == RED)
				{
					uncle->_col = parent->_col = BLACK;
					grandfater->_col = RED;
					//向上調(diào)整
					cur = grandfater;
					parent = cur->_parent;
				}
				else
				{
					//情況2:u不存在/u存在為黑色
					//g
					//    p
					//        c
					if (cur == parent->_right)
					{
						RotateL(grandfater);
						grandfater->_col = RED;
						parent->_col = BLACK;
					}
					//情況3
					//     g
					 //         p
					 //      c
					else
					{
						RotateR(parent);
						RotateL(grandfater);
						cur->_col = BLACK;
						grandfater->_col = RED;
					}
					break;
				}
			}
		}
		//根變黑
		_root->_col = BLACK;
		return make_pair(iterator(newnode),true);
	}
	void RotateL(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;
		parent->_right = subRL;
		if (subRL)
			subRL->_parent = parent;
		Node* ppNode = parent->_parent;
		subR->_left = parent;
		parent->_parent = subR;
		if (ppNode == nullptr)
		{
			_root = subR;
			_root->_parent = nullptr;
		}
		else
		{
			if (ppNode->_left == parent)
			{
				ppNode->_left = subR;
			}
			else
			{
				ppNode->_right = subR;
			}
			subR->_parent = ppNode;
		}
	}
	void RotateR(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;
		parent->_left = subLR;
		if (subLR)
			subLR->_parent = parent;
		Node* ppNode = parent->_parent;
		parent->_parent = subL;
		subL->_right = parent;
		if (ppNode == nullptr)
		{
			_root = subL;
			_root->_parent = nullptr;
		}
		else
		{
			if (ppNode->_left == parent)
			{
				ppNode->_left = subL;
			}
			else
			{
				ppNode->_right = subL;
			}
			subL->_parent = ppNode;
		}
	}
	void InOrder()
	{
		_InOrder(_root);
	}
	void _InOrder(Node* root)
	{
		if (root == nullptr)
			return;
		_InOrder(root->_left);
		cout << root->_kv.first << ":" << root->_kv.second << endl;
		_InOrder(root->_right);
	}
	bool Check(Node* root, int blackNum, int ref)
	{
		if (root == nullptr)
		{
			//cout << blackNum << endl;
			if (blackNum != ref)
			{
				cout << "違反規(guī)則:本條路徑的黑色結(jié)點的數(shù)量根最左路徑不相等" << endl;
				return false;
			}
			return true;
		}
		if (root->_col == RED && root->_parent->_col == RED)
		{
			cout << "違反規(guī)則:出現(xiàn)連續(xù)的紅色結(jié)點" << endl;
			return false;
		}
		if (root->_col == BLACK)
		{
			++blackNum;
		}
		return Check(root->_left, blackNum, ref)
			&& Check(root->_right, blackNum, ref);
	}
	bool IsBalance()
	{
		if (_root == nullptr)
		{
			return true;
		}
		if (_root->_col != BLACK)
		{
			return false;
		}
		int ref = 0;
		Node* left = _root;
		while (left)
		{
			if (left->_col == BLACK)
			{
				++ref;
			}
			left = left->_left;
		}
		return Check(_root, 0, ref);
	}
private:
	Node* _root = nullptr;
};

到此這篇關于C++ map與set封裝實現(xiàn)過程講解的文章就介紹到這了,更多相關C++ map與set內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++ 中消息隊列函數(shù)實例詳解

    C++ 中消息隊列函數(shù)實例詳解

    這篇文章主要介紹了C++ 中消息隊列函數(shù)實例詳解的相關資料,需要的朋友可以參考下
    2017-06-06
  • C++如何刪除map容器中指定值的元素詳解

    C++如何刪除map容器中指定值的元素詳解

    map容器是C++ STL中的重要一員,刪除map容器中value為指定元素的問題是我們經(jīng)常與遇到的一個問題,下面這篇文章主要給大家介紹了關于利用C++如何刪除map容器中指定值的元素的相關資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-06-06
  • C++實現(xiàn)LeetCode(32.最長有效括號)

    C++實現(xiàn)LeetCode(32.最長有效括號)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(32.最長有效括號),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Matlab繪制有趣的羅盤時鐘的示例代碼

    Matlab繪制有趣的羅盤時鐘的示例代碼

    這篇文章主要介紹了如何利用Matlab實現(xiàn)繪制有趣的羅盤時鐘,文中的示例代碼講解詳細,對我們學習Matlab有一定的幫助,需要的可以參考一下
    2023-01-01
  • C/C++位段超詳細整理大全

    C/C++位段超詳細整理大全

    以位為單位來定義結(jié)構體中的成員變量所占的空間內(nèi)存,含有位段的結(jié)構體稱為位段結(jié)構,這篇文章主要給大家介紹了關于C/C++位段的相關資料,需要的朋友可以參考下
    2024-01-01
  • C/C++字符串與數(shù)字互轉(zhuǎn)的實現(xiàn)

    C/C++字符串與數(shù)字互轉(zhuǎn)的實現(xiàn)

    這篇文章主要介紹了C/C++字符串與數(shù)字互轉(zhuǎn)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • C++調(diào)用C函數(shù)實例詳解

    C++調(diào)用C函數(shù)實例詳解

    這篇文章主要介紹了C++調(diào)用C函數(shù)實例詳解的相關資料,需要的朋友可以參考下
    2017-07-07
  • C++如何將十六進制字符串轉(zhuǎn)換為二進制字符串

    C++如何將十六進制字符串轉(zhuǎn)換為二進制字符串

    這篇文章主要介紹了C++如何將十六進制字符串轉(zhuǎn)換為二進制字符串問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 詳解C/C++ Linux出錯處理函數(shù)(strerror與perror)的使用

    詳解C/C++ Linux出錯處理函數(shù)(strerror與perror)的使用

    我們知道,系統(tǒng)函數(shù)調(diào)用不能保證每次都成功,必須進行出錯處理,這樣一方面可以保證程序邏輯正常,另一方面可以迅速得到故障信息。本文主要為大家介紹兩個出錯處理函數(shù)(strerror、perror)的使用,需要的可以參考一下
    2023-01-01
  • C語言實現(xiàn)哈希搜索算法及原理詳解

    C語言實現(xiàn)哈希搜索算法及原理詳解

    本文主要介紹了C語言實現(xiàn)哈希搜索算法及原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06

最新評論

敖汉旗| 荆州市| 永安市| 宕昌县| 双流县| 普安县| 安吉县| 柳河县| 武宁县| 福鼎市| 松原市| 山西省| 翼城县| 吐鲁番市| 军事| 宿迁市| 虹口区| 延庆县| 克拉玛依市| 临颍县| 常宁市| 泗阳县| 旅游| 尼玛县| 封丘县| 马鞍山市| 太湖县| 凤城市| 津南区| 新兴县| 清徐县| 黔江区| 乡宁县| 钟山县| 扎赉特旗| 德江县| 克什克腾旗| 海门市| 商洛市| 鄱阳县| 蓝田县|