国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C++】STL之map、set類源碼剖析

這篇具有很好參考價值的文章主要介紹了【C++】STL之map、set類源碼剖析。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

概述

算法

源碼

Iterator.h

RBTree.h

Map.h

Set.h

test.cpp


概述

map和set都是STL中的關(guān)聯(lián)式容器,而vector、list、deque是序列式容器。

map是映像,set是集合,map元素的數(shù)據(jù)類型是std::pair<K,V>格式(key/value形成映像),set元素的數(shù)據(jù)類型只有key值。

map和set的實現(xiàn)是對紅黑樹的封裝,map根據(jù)key值進行排序,map和set的key值都是不可修改的,但是map的value值可以修改。

map和set支持迭代器、反向迭代器、常量迭代器,并且通過精妙的泛型設(shè)計,大大簡化了代碼,但是完成兩個STL容器的基本功能封裝,依舊需要千行代碼左右。

算法

本文里面的紅黑樹模塊相較于上一篇博客,做了部分修改,設(shè)計了紅黑樹的迭代器,并將迭代器單獨作為一個模塊,通過普通迭代器構(gòu)造出反向迭代器,這里采用的設(shè)計思路與之前 list 容器的迭代器設(shè)計思路是相同的。

紅黑樹在普通迭代器類中,設(shè)計出通過普通迭代器拷貝出const迭代器,這樣解決了set模塊的insert函數(shù)的返回值由紅黑樹的iterator轉(zhuǎn)換為const_iterator問題。

紅黑樹迭代器的自增、自減都有其獨特的算法,但是本文中的紅黑樹結(jié)構(gòu),與stl標準庫中的紅黑樹略有不同,本文的紅黑樹沒有一個空的頭結(jié)點,即:當?shù)鞯絜nd(),即迭代器指向nullptr。而在stl標準庫中,迭代器走到end()時,迭代器指向空的頭結(jié)點。

紅黑樹的構(gòu)造可以通過元素插入構(gòu)造或者拷貝構(gòu)造,拷貝構(gòu)造設(shè)計了迭代器構(gòu)造,這也是拷貝構(gòu)造的核心。map和set的迭代器構(gòu)造、拷貝構(gòu)造、賦值構(gòu)造本質(zhì)都是調(diào)用紅黑樹的迭代器構(gòu)造。

紅黑樹的泛型設(shè)計十分精妙(紅黑樹自身并不知道自己是要構(gòu)造出一個map還是set,但是他必須兼容這兩種容器的所有特性),并通過仿函數(shù)KofT設(shè)計,實現(xiàn)了從傳入的元素數(shù)據(jù)(key值或key/value鍵值對)之中提取到key值進行排序

set模塊的迭代器設(shè)計十分精妙,因為set里面元素都是key值,而紅黑樹的key值是不允許修改的,所以無論是set的普通迭代器iterator還是const_iterator,其本質(zhì)都是const_iterator,所以set在設(shè)計時用const_iterator來重命名iterator,在普通迭代器的構(gòu)造函數(shù)時加上了const修飾,而省略了const_iterator的構(gòu)造函數(shù),使iterator的構(gòu)造函數(shù)能夠?qū)onst_iterator構(gòu)成重載。

map的 "[ ]" 運算符有特殊功能,即可以通過 "[ ] " 來進行數(shù)據(jù)插入、查找、統(tǒng)計,原理是:若 "[ ]" 里面數(shù)據(jù)的key值已經(jīng)存在的話,則插入失敗,insert函數(shù)返回已有節(jié)點的迭代器和一個bool值false,然后 "[ ] " 運算符返回這個迭代器(pair<key, value>)的第二個數(shù)據(jù)(value);若 "[ ]"? 里面數(shù)據(jù)的key不存在,則插入成功,insert函數(shù)返回新插入節(jié)點的迭代器和bool值true,然后 "[ ]" 運算符返回這個鍵值對迭代器的value值。因此我們可以通過這個原理對鍵值對的第二個數(shù)據(jù)為整型類型的數(shù)據(jù)進行計數(shù)操作。文章來源地址http://www.zghlxwxcb.cn/news/detail-434741.html

源碼

Iterator.h

#pragma once

enum Colour
{
	RED,
	BLACK
};

template<class T>
struct RBTreeNode
{
	T _data;
	RBTreeNode<T>* _left;
	RBTreeNode<T>* _right;
	RBTreeNode<T>* _parent;
	Colour _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)
	{}

	// 普通迭代器構(gòu)造const迭代器
	RBTreeIterator(const iterator& it)
	{
		_node = it._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++(int)
	{
		Self tmp(*this);
		++(*this);
		return tmp;
	}

	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;
	}
	Self operator--(int)
	{
		Self tmp(*this);
		--(*this);
		return tmp;
	}

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

template<class Iterator, class Ref, class Ptr>
struct RBTreeReverseIterator
{
	typedef RBTreeReverseIterator<Iterator, Ref, Ptr> Self;

	Iterator _it;
	RBTreeReverseIterator(Iterator it)
		: _it(it)
	{}

	Ref operator*()
	{
		Iterator tmp = _it;
		return *tmp;
	}
	Ptr operator->()
	{
		return &(operator*());
	}

	Self& operator++()
	{
		--_it;
		return *this;
	}
	Self operator++(int)
	{
		Self tmp(*this);
		--_it;
		return tmp;
	}

	Self& operator--()
	{
		++_it;
		return *this;
	}
	Self operator--(int)
	{
		Self tmp(*this);
		++_it;
		return tmp;
	}

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

RBTree.h

#pragma once
#include "Iterator.h"

template<class K, class T, class KofT>
class RBTree
{
	// 私有
	typedef RBTreeNode<T> Node;
public:
	typedef RBTreeIterator<T, T&, T*> iterator;
	typedef RBTreeIterator<T, const T&, const T*> const_iterator;
	typedef RBTreeReverseIterator<iterator, T&, T*> reverse_iterator;
	typedef RBTreeReverseIterator<const_iterator, const T&, const T*> const_reverse_iterator;

	iterator begin()
	{
		Node* left = _root;
		while (left && left->_left)
		{
			left = left->_left;
		}

		return iterator(left);
	}
	iterator end()
	{
		return iterator(nullptr);
	}

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

	reverse_iterator rbegin()
	{
		Node* right = _root;
		while (right && right->_right)
		{
			right = right->_right;
		}

		return reverse_iterator(iterator(right));
	}
	reverse_iterator rend()
	{
		return reverse_iterator(iterator(nullptr));
	}

	const_reverse_iterator rbegin()const
	{
		Node* right = _root;
		while (right && right->_right)
		{
			right = right->_right;
		}

		return const_reverse_iterator(const_iterator(right));
	}
	const_reverse_iterator rend()const
	{
		return const_reverse_iterator(const_iterator(nullptr));
	}

	// 迭代器構(gòu)造
	template<class Iterator>
	RBTree(Iterator first, Iterator last)
	{
		_root = nullptr;
		while (first != last)
		{
			insert(*first);
			++first;
		}
	}

	RBTree()
		: _root(nullptr)
	{}

	std::pair<iterator, bool> insert(const T& data)
	{
		if (_root == nullptr)
		{
			_root = new Node(data);
			_root->_col = BLACK;
			return std::make_pair(iterator(_root), true);
		}

		KofT 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 std::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;
		}

		// 變色、旋轉(zhuǎn)
		while (parent && parent->_col == RED)
		{
			Node* grandfather = parent->_parent;
			if (parent == grandfather->_left)
			{
				Node* uncle = grandfather->_right;

				if (uncle && uncle->_col == RED)
				{
					// 情況1:叔叔存在且為紅
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;

					cur = grandfather;
					parent = cur->_parent;
				}
				else
				{
					if (cur == parent->_left)
					{
						// 情況2: 右單旋
						rotate_right(grandfather);
						parent->_col = BLACK;
						grandfather->_col = RED;
					}
					else
					{
						// 情況3: 左右雙旋
						rotate_left(parent);
						rotate_right(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}
					break;
				}
			}
			else
			{
				Node* uncle = grandfather->_left;

				if (uncle&& uncle->_col == RED)
				{
					parent->_col = uncle->_col = BLACK;
					grandfather->_col = RED;

					cur = grandfather;
					parent = cur->_parent;
				}
				else
				{
					if (cur == parent->_right)
					{
						// 情況2: 左單旋
						rotate_left(grandfather);
						parent->_col = BLACK;
						grandfather->_col = RED;
					}
					else
					{
						// 情況3: 右左雙旋
						rotate_right(parent);
						rotate_left(grandfather);
						cur->_col = BLACK;
						grandfather->_col = RED;
					}
					break;
				}
			}

		}

		_root->_col = BLACK;

		return std::make_pair(iterator(newNode), true);
	}

	void rotate_right(Node* parent)
	{
		Node* subL = parent->_left;
		Node* subLR = subL->_right;

		parent->_left = subLR;
		if (subLR)
		{
			subLR->_parent = parent;
		}

		subL->_right = parent;
		Node* ppNode = parent->_parent;
		parent->_parent = subL;
		if (ppNode == nullptr)
		{
			subL->_parent = nullptr;
			_root = subL;
		}
		else
		{
			if (parent == ppNode->_left)
			{
				ppNode->_left = subL;
			}
			else
			{
				ppNode->_right = subL;
			}
			subL->_parent = ppNode;
		}
	}

	void rotate_left(Node* parent)
	{
		Node* subR = parent->_right;
		Node* subRL = subR->_left;

		parent->_right = subRL;
		if (subRL)
		{
			subRL->_parent = parent;
		}

		subR->_left = parent;
		Node* ppNode = parent->_parent;
		parent->_parent = subR;
		if (ppNode == nullptr)
		{
			subR->_parent = nullptr;
			_root = subR;
		}
		else
		{
			if (parent == ppNode->_left)
			{
				ppNode->_left = subR;
			}
			else
			{
				ppNode->_right = subR;
			}
			subR->_parent = ppNode;
		}
	}

	void in_order()
	{
		_in_order(_root);
		std::cout << std::endl;
	}

	bool is_balance()
	{
		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 _is_balance(_root, 0, ref);
	}

private:
	void _in_order(Node* root)
	{
		if (root == nullptr)
		{
			return;
		}
		_in_order(root->_left);
		std::cout << root->_data << std::endl;
		_in_order(root->_right);
	}

	// 檢查是否有聯(lián)系的紅節(jié)點
	bool _is_balance(Node* root, int blackNum, const int ref)
	{
		if (root == nullptr)
		{
			if (blackNum != ref)
			{
				std::cout << "路徑黑色節(jié)點跟最左路徑不相等" << std::endl;
				return false;
			}
			return true;
		}

		if (root->_col == RED && root->_parent->_col == RED)
		{
			std::cout << "出現(xiàn)連續(xù)紅節(jié)點: " << root->_data.first << ", " << root->_parent->_data.first << std::endl;
			return false;
		}

		if (root->_col == BLACK)
		{
			++blackNum;
		}

		return _is_balance(root->_left, blackNum, ref)
			&& _is_balance(root->_right, blackNum, ref);
	}

private:
	Node* _root = nullptr;
};

Map.h

#pragma once

#include "RBTree.h"

template<class K, class V>
class Map
{
	struct MapKofT
	{
		const K& operator()(const std::pair<const K, V>& kv)
		{
			return kv.first;
		}
	};
public:
	typedef typename RBTree<K, std::pair<const K, V>, MapKofT>::iterator iterator;
	typedef typename RBTree<K, std::pair<const K, V>, MapKofT>::const_iterator const_iterator;
	typedef typename RBTree<K, std::pair<const K, V>, MapKofT>::reverse_iterator reverse_iterator;
	typedef typename RBTree<K, std::pair<const K, V>, MapKofT>::const_reverse_iterator const_reverse_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();
	}

	reverse_iterator rbegin()
	{
		return _t.rbegin();
	}
	reverse_iterator rend()
	{
		return _t.rend();
	}

	const_reverse_iterator rbegin()const
	{
		return _t.rbegin();
	}
	const_reverse_iterator rend()const
	{
		return _t.rend();
	}

	template<class Iterator>
	Map(Iterator first, Iterator last)
	{
		_t = RBTree<K, std::pair<const K, V>, MapKofT>(first, last);
	}

	void swap(Map<K, V>& m)
	{
		std::swap(_t, m._t);
	}

	Map()
		: _t(RBTree<K, std::pair<const K, V>, MapKofT>())
	{}
	Map(const Map<K, V>& m)
	{
		Map<K, V> tmp(m._t.begin(), m._t.end());
		swap(tmp);
	}
	Map<K, V>& operator=(const Map<K, V> m)
	{
		swap(m);
		return *this;
	}

	std::pair<iterator, bool> insert(const std::pair<const K, V>& kv)
	{
		return _t.insert(kv);
	}

	V& operator[](const K& key)
	{
		std::pair<iterator, bool> ret = insert(std::make_pair(key, V()));
		return ret.first->second;
	}

private:
	RBTree<K, std::pair<const K, V>, MapKofT> _t;
};

Set.h

#pragma once

#include "RBTree.h"

template<class K>
class Set
{
	struct SetKofT
	{
		const K& operator()(const K& key)
		{
			return key;
		}
	};
public:
	typedef typename RBTree<K, K, SetKofT>::const_iterator iterator;
	typedef typename RBTree<K, K, SetKofT>::const_iterator const_iterator;
	typedef typename RBTree<K, K, SetKofT>::const_reverse_iterator reverse_iterator;
	typedef typename RBTree<K, K, SetKofT>::const_reverse_iterator const_reverse_iterator;

	iterator begin()const
	{
		return _t.begin();
	}
	iterator end()const
	{
		return _t.end();
	}

	reverse_iterator rbegin()const
	{
		return _t.rbegin();
	}
	reverse_iterator rend()const
	{
		return _t.rend();
	}

	template<class Iterator>
	Set(Iterator first, Iterator last)
	{
		_t = RBTree<K, K, SetKofT>(first, last);
	}

	void swap(Set<K>& s)
	{
		std::swap(_t, s._t);
	}

	Set()
		: _t(RBTree<K, K, SetKofT>())
	{}
	Set(const Set<K>& s)
	{
		Set<K> tmp(s.begin(), s.end());
		swap(tmp);
	}
	Set<K>& operator=(const Set<K> s)
	{
		swap(s);
		return *this;
	}

	std::pair<iterator, bool> insert(const K& k)
	{
		std::pair<typename RBTree<K, K, SetKofT>::iterator, bool> ret = _t.insert(k);
		return std::pair<iterator, bool>(ret.first, ret.second);
	}

private:
	RBTree<K, K, SetKofT> _t;
};

test.cpp

#include <iostream>
#include <string>
#include <vector>
#include "Map.h"
#include "Set.h"

void test_map()
{
	int a[] = { 8, 4, 12, 2, 6, 10, 30, 14, 32, 28 };

	Map<int, int> m;
	for (auto e : a)
	{
		m.insert(std::make_pair(e, e));
	}

	Map<int, int>::iterator it = m.begin();
	while (it != m.end())
	{
		std::cout << (*it).first << ": " << (*it).second << std::endl;
		//++it;
		it++;
	}
	std::cout << std::endl;
	for (auto e : m)
	{
		std::cout << e.first << ": " << e.second << std::endl;
	}
	std::cout << std::endl;

	Map<int, int>::reverse_iterator rit = m.rbegin();
	while (rit != m.rend())
	{
		std::cout << rit->first << ": " << rit->second << std::endl;
		rit++;
	}
	std::cout << std::endl;

	const Map<int, int> m1(m.begin(), m.end());
	Map<int, int>::const_iterator cit = m1.begin();
	while (cit != m1.end())
	{
		std::cout << cit->first << ": " << cit->second << std::endl;
		cit++;
	}
	std::cout << std::endl;

	const Map<int, int> m2(m1);
	Map<int, int>::const_reverse_iterator crit = m2.rbegin();
	while (crit != m2.rend())
	{
		std::cout << crit->first << ": " << crit->second << std::endl;
		++crit;
	}
	std::cout << std::endl;

	Map<int, int> m3 = m2;
	for (auto& e : m3)
	{
		// map的key不可修改,value可改
		//e.first += 1;
		e.second /= 2;
		std::cout << e.first << ": " << e.second << std::endl;
	}
	std::cout << std::endl;

	std::vector<std::string> food = {
		"蛋糕", "西瓜", "啤酒", "蘋果", "香蕉", "蛋糕", "牛肉",
		"西瓜", "蘋果", "啤酒", "西瓜", "牛肉", "蛋糕", "蛋糕",
		"西瓜", "西瓜", "牛肉", "蘋果", "香蕉", "蛋糕", "西瓜"
	};
	Map<std::string, int> foodMap;
	for (auto& e : food)
	{
		foodMap[e]++;
	}
	for (auto& e : foodMap)
	{
		std::cout << e.first << ": " << e.second << std::endl;
	}
	std::cout << std::endl;
}

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())
	{
		std::cout << *it << ' ';
		++it;
	}
	std::cout << std::endl;
	for (const auto& e : s)
	{
		std::cout << e << ' ';
	}
	std::cout << std::endl;

	Set<int>::reverse_iterator rit = s.rbegin();
	while (rit != s.rend())
	{
		std::cout << *rit << ' ';
		++rit;
	}
	std::cout << std::endl;

	const Set<int> s1(s.begin(), s.end());
	Set<int>::const_iterator cit = s1.begin();
	while (cit != s1.end())
	{
		std::cout << *cit << ' ';
		++cit;
	}
	std::cout << std::endl;

	const Set<int> s2(s1);
	Set<int>::const_reverse_iterator crit = s2.rbegin();
	while (crit != s2.rend())
	{
		std::cout << *crit << ' ';
		++crit;
	}
	std::cout << std::endl;

	const Set<int> s3 = s2;
	for (auto& e : s3)
	{	
		// set的值不可修改
		// e++;
		std::cout << e << ' ';
	}
	std::cout << std::endl;
}

int main()
{
	test_map();
	test_set();
	
	return 0;
}

到了這里,關(guān)于【C++】STL之map、set類源碼剖析的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • C++高級編程——STL:list容器、set容器和map容器

    本專欄記錄C++學(xué)習(xí)過程包括C++基礎(chǔ)以及數(shù)據(jù)結(jié)構(gòu)和算法,其中第一部分計劃時間一個月,主要跟著黑馬視頻教程,學(xué)習(xí)路線如下, 不定時更新,歡迎關(guān)注 。 當前章節(jié)處于: ---------第1階段-C++基礎(chǔ)入門 ---------第2階段實戰(zhàn)-通訊錄管理系統(tǒng), ---------第3階段-C++核心編程, -----

    2024年01月25日
    瀏覽(23)
  • 【C++】STL——用一顆紅黑樹封裝出map和set

    【C++】STL——用一顆紅黑樹封裝出map和set

    我們都知道set是K模型的容器,而map是KV模型的容器,但是它倆的底層都是用紅黑樹實現(xiàn)的,上篇博文中我們模擬實現(xiàn)了一顆紅黑樹,接下來將對其進行改造,繼而用一顆紅黑樹封裝出map和set。 本質(zhì)上map和set其內(nèi)部的主要功能都是套用了紅黑樹現(xiàn)成的接口,只是稍作改動即可

    2023年04月15日
    瀏覽(18)
  • 【C++】 使用紅黑樹模擬實現(xiàn)STL中的map與set

    【C++】 使用紅黑樹模擬實現(xiàn)STL中的map與set

    前面的文章我們學(xué)習(xí)了紅黑樹,也提到了C++STL中的map和set的底層其實就是用的紅黑樹來實現(xiàn)的(而map和set的使用我們前面也學(xué)過了)。 既然紅黑樹我們也學(xué)習(xí)過了,那這篇文章我們就用紅黑樹來簡單實現(xiàn)一下STL中的map和set,重點是學(xué)習(xí)它的框架。 上一篇文章我們實現(xiàn)了紅黑

    2024年02月12日
    瀏覽(23)
  • C++:stl中set(multiset)和map(multimap)的介紹和使用

    C++:stl中set(multiset)和map(multimap)的介紹和使用

    本文主要從概念、常用接口和使用方法方面介紹set(multiset)和map(multimap)。 目錄 一、概念介紹 1.關(guān)聯(lián)式容器 2.鍵值對 3. 樹形結(jié)構(gòu)的關(guān)聯(lián)式容器 二、set和multiset 1.set的介紹 2.set使用 1. set模板參數(shù)列表 2. set構(gòu)造 3. set迭代器 4. set容量 5. set修改操作 6.set使用舉例 3.multiset介紹 4.mul

    2024年02月08日
    瀏覽(25)
  • 【C++練級之路】【Lv.17】【STL】set類和map類的模擬實現(xiàn)

    【C++練級之路】【Lv.17】【STL】set類和map類的模擬實現(xiàn)

    快樂的流暢:個人主頁 個人專欄:《C語言》《數(shù)據(jù)結(jié)構(gòu)世界》《進擊的C++》 遠方有一堆篝火,在為久候之人燃燒! STL庫中的set類和map類,其底層原理都是 通過紅黑樹來實現(xiàn) 的。盡管set和map可以各自實現(xiàn)一棵紅黑樹,但是為了提高代碼的復(fù)用率,STL庫中將紅黑樹進行了一定

    2024年04月16日
    瀏覽(30)
  • 【C++進階04】STL中map、set、multimap、multiset的介紹及使用

    【C++進階04】STL中map、set、multimap、multiset的介紹及使用

    vector/list/deque… 這些容器統(tǒng)稱為 序列式容器 因為其底層為線性序列的數(shù)據(jù)結(jié)構(gòu) 里面存儲的是元素本身 map/set… 這些容器統(tǒng)稱為 關(guān)聯(lián)式容器 關(guān)聯(lián)式容器也是用來存儲數(shù)據(jù)的 與序列式容器不同的是 其里面存儲的是key, value結(jié)構(gòu)的鍵值對 在數(shù)據(jù)檢索時比序列式容器效率更高 “鍵

    2024年02月03日
    瀏覽(24)
  • 【C++高階(二)】熟悉STL中的map和set --了解KV模型和pair結(jié)構(gòu)

    【C++高階(二)】熟悉STL中的map和set --了解KV模型和pair結(jié)構(gòu)

    ??博主CSDN主頁:杭電碼農(nóng)-NEO?? ? ?專欄分類:C++從入門到精通? ? ??代碼倉庫:NEO的學(xué)習(xí)日記?? ? ??關(guān)注我??帶你學(xué)習(xí)C++ ? ???? 在學(xué)習(xí)了二叉搜索樹后,現(xiàn)在 就可以來學(xué)習(xí)map和set了,雖然 它們的底層是紅黑樹結(jié)構(gòu),但是紅黑樹 的本質(zhì)也是一顆二叉搜索樹! 本質(zhì)重點: 本

    2024年02月05日
    瀏覽(47)
  • 【C++入門到精通】哈希 (STL) _ unordered_map _ unordered_set [ C++入門 ]

    【C++入門到精通】哈希 (STL) _ unordered_map _ unordered_set [ C++入門 ]

    歡迎各位大佬們的關(guān)顧,本文將介紹unordered系列容器以及其中的兩個重要成員: unordered_map 和 unordered_set 。unordered_map是一種無序的關(guān)聯(lián)容器,它使用哈希表來存儲鍵值對,并提供高效的插入、查找和刪除操作。在本文中,我們將首先介紹unordered_map的基本概念和特點,然后詳

    2024年02月08日
    瀏覽(20)
  • C++ 哈希+unordered_map+unordered_set+位圖+布隆過濾器(深度剖析)

    C++ 哈希+unordered_map+unordered_set+位圖+布隆過濾器(深度剖析)

    想象一下,你有一個巨大的圖書館,里面擺滿了成千上萬本書。如果你想要找到其中一本特定的書,你會怎么做?如果你按照書的編號來有序地排列它們,找到特定的書本可能會很容易。但是,如果書籍是隨機地擺放,你可能需要逐本地查找,這個過程會非常耗時。 而哈希函

    2024年02月21日
    瀏覽(24)
  • 【C++】STL——用一個哈希表封裝出unordered_map和unordered_set

    【C++】STL——用一個哈希表封裝出unordered_map和unordered_set

    根據(jù)先前對unordered_map和unordered_set的學(xué)習(xí),我們得知其底層是借助哈希表來實現(xiàn)的,接下來我們會使用上篇博客實現(xiàn)的開散列哈希表來模擬實現(xiàn)unordered_map和unordered_set,哈希表源代碼鏈接: Hash/Hash/HashBucket.h · wei/cplusplus - 碼云 - 開源中國 (gitee.com) 下面我們對哈希表進行改造,

    2023年04月18日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包