STL之红黑树容器:set,hash_set,multiset,hash_map,multimap

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:  1红黑树set(不能包含重复元素) 案例1:红黑树容器set,插入,查找 #include<iostream> #include<set> usingnamespacestd;   //set中不能有重复的元素,它是一个红黑树容器 voidmain() {    set<int>myset


1红黑树set(不能包含重复元素)

案例1:红黑树容器set,插入,查找

#include<iostream>

#include<set>

usingnamespacestd;

 

//set中不能有重复的元素,它是一个红黑树容器

voidmain()

{

   set<int>myset;

   myset.insert(10);

   myset.insert(9);

   myset.insert(8);

   myset.insert(7);

   myset.insert(5);

   myset.insert(5);

   myset.insert(6);

   myset.insert(7);

   //myset.insert(7);重复会被舍弃

   autofindpos =myset.find(10);

   cout <<" find -> " << *findpos << " \n";

 

   autoib =myset.begin();

   autoie =myset.end();

   for (;ib !=ie;ib++)

   {

       cout << *ib << "  ";

   }

   cout <<"\n" <<myset.size() << endl;

   cin.get();

}

 

案例2

#include<iostream>

#include<set>

 

usingnamespacestd;

 

structstrless

{

   //二分查找法依赖于有序,字符串有序

   bool operator()(constchar *str1,constchar *str2)//二分查找法依赖于有序,字符串有序

   {

       returnstrcmp(str1,str2) < 0;

   }

};

 

//红黑树,处理纯数字非常少,经常处理类对象以及字符串

voidmain()

{

   constchar *cmd[] = { "abc","calc","notepad","const","xyz","ghj" };

   //strless():表示比大小的

   //set是一个红黑树,不可以用下标的方式

   set<constchar*,strless>myset(cmd,cmd + 6,strless());

   myset.insert("1234");

   myset.insert("4567");

 

   //pair起到获取插入返回值,第一个类型,类型比大小的方式

   //pair相当于是一对的意思,同时可以装两个东西

   pair<set<constchar *>::iterator,bool>p =myset.insert("9876");

   cout <<"pair start" <<endl;

   cout << *(p.first) << " " <<p.second << endl;

   cout <<"pair over" <<endl;

   cout <<"----正向迭代---" << endl;

 

   autoib =myset.begin();

   autoie =myset.end();

   for (;ib !=ie;ib++)

   {

       cout << *ib << endl;

   }

   

   cout <<"----反向迭代---" << endl;

 

   autorb =myset.rbegin();

   autore =myset.rend();

   for (;rb !=re;rb++)

   {

       cout << *rb << endl;

   }

   //查找

   set<constchar *,strless>::iteratorpfind =myset.find("xyz");

   std::cout << "\n\n\n" << *pfind << endl;

 

   cin.get();

}

运行结果:

2. hash_set

案例1

#include<hash_set>

#include<iostream>

#include<algorithm>

#include<string>

 

usingnamespacestd;

 

voidmain()

{

   hash_set<constchar *>hs;//C++11自带子字符串的哈希

 

   hs.insert("chian");

   hs.insert("chi123an");

   hs.insert("chi23an");

   hs.insert("chzcian");

   hs.insert("1chzcian");

 

   //这里得到的是一个指针

   autopfind =hs.find("chi23an");

 

   if (pfind == hs.end())

   {

       std::cout << "没有";

   }

   else

   {

       std::cout << *pfind;

   }

   cin.get();

   //运行结果:chi23an

}

案例2

#include<hash_set>

#include<iostream>

#include<algorithm>

#include<string>

 

usingnamespacestd;

 

voidmain()

{

   hash_set<int>hs;

   hs.insert(91);

   hs.insert(21);

   hs.insert(41);

 

   autoib =hs.begin();

   autoie =hs.end();

   for (;ib !=ie;ib++)

   {

       cout << *ib << endl;

   }

   //查找211

   autopfind =hs.find(211);

   if (pfind == ie)

   {

       std::cout << "没有";

   }

   else

   {

       std::cout << *pfind;

   }

   cin.get();

}

3.multiset(每个元素的节点是一个链表)

案例1:multisetset的区别是:multiset允许重复

#include<iostream>

#include<set>

#include<stdio.h>

#include<list>

#include<vector>

#include<algorithm>

#include<functional>

 

usingnamespacestd;

//multisetset的区别是允许重复

voidmain()

{

   multiset<int>myset; //头文件set

   myset.insert(11);

   myset.insert(12);

   myset.insert(13);

   myset.insert(10);

   myset.insert(10);

   myset.insert(100);

   autoib =myset.begin();

   autoie =myset.end();

 

   for (;ib !=ie;ib++)

   {

       std::cout << *ib <<std::endl;

       printf("%p,%p\n",ib,ib._Ptr);//ib本质是智能指针

       //建议使用下面的方式打印出外部指针和内部指针

       printf("%p\n",ib);//ib本质是智能指针

       //打印内部指针

       printf("%p\n",ib._Ptr);//ib本质是智能指针

   }

   cin.get();

}

运行结果是:

案例2

#define_CRT_SECURE_NO_WARNINGS

#include<set>

#include<iostream>

#include<string>

 

//multiset每一个节点都是一个链表,set每个节点就是一个节点

usingnamespacestd;

 

structstudent

{

   intid;

   charname[30];

};

 

//排序

structstuless

{

   bool operator()(conststudent &s1,conststudent &s2)

   {

       returns1.id < s2.id;

   }

};

 

voidmain()

{

   studentsarray[3] = { { 10,"tansheng" }, { 3,"liguilong" }, { 4,"xiongfei" } };

   multiset<student,stuless>myset(sarray,sarray + 3,stuless());

   studentstu1;

   stu1.id = 20;

   strcpy(stu1.name,"mouzhiwei");

   myset.insert(stu1);

   strcpy(stu1.name,"mouzhiwei1");

   myset.insert(stu1);

   strcpy(stu1.name,"mouzhiwei2");

   myset.insert(stu1);

   autoib =myset.begin();

   autoie =myset.end();

   for (;ib !=ie;ib++)

   {

       cout << (*ib).id << " " << (*ib).name << endl;

   }

 

   cin.get();

}

4.hash_map

案例:

#include<hash_map>//也是红黑树,是一个映射

 

#include<iostream>

#include<map>

 

usingnamespacestd;

 

voidmain()

{

   map<int,constchar *>m;

   m.insert(pair<int,constchar *>(201,"司令1"));

   m.insert(pair<int,constchar *>(101,""));

   m.insert(pair<int,constchar *>(401,"司令11111"));

   m.insert(pair<int,constchar *>(301,"司令"));

 

   autoib =m.begin();

   autoie =m.end();

   for (;ib !=ie;ib++)

   {

       cout << (*ib).first << "  " << (*ib).second << "\n";

   }

   std::cout << "------------" <<std::endl;

   {

       hash_map<int,constchar *>m;

       m.insert(pair<int,constchar *>(201,"司令1"));

       m.insert(pair<int,constchar *>(101,""));

       m.insert(pair<int,constchar *>(401,"司令11111"));

       m.insert(pair<int,constchar *>(301,"司令"));

 

       std::cout << "---正向迭代---" << std::endl;

       autoib =m.begin();

       autoie =m.end();

       for (;ib !=ie;ib++)

       {

           cout << (*ib).first << "  " << (*ib).second << "\n";

       }

       autotofind =m.find(1101);

       if (tofind == ie)

       {

           cout <<"没有找到";

       }

       else

       {

           cout <<"\n\n\n" << (*tofind).first << " " << (*tofind).second;

       }

   }

 

   cin.get();

}

运行结果:

5. multimap每一个一个节点是映射的链表的开头

案例1

#include<iostream>

#include<map>

 

usingnamespacestd;

//map,mutlimap区别是map每一个节点是一个映射

//multimap每一个一个节点是映射的链表的开头

voidmain()

{

   map<constchar*,int>m;

   m.insert(pair<constchar *,int>("司令1", 101));

   m.insert(pair<constchar *,int>("司令2", 102));

   m.insert(pair<constchar *,int>("司令3", 103));

   m.insert(pair<constchar *,int>("司令1", 104));

 

   map<constchar *,int>::iteratorib =m.begin();

   autoie =m.end();

   for (;ib !=ie;ib++)

   {

       cout << (*ib).first << "  " << (*ib).second << "\n";

   }

 

   cin.get();

}

运行结果:

 

 

 

目录
相关文章
|
9月前
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
247 2
|
6月前
|
编译器 C++ 容器
用一棵红黑树同时封装出map和set
再完成上面的代码后,我们的底层代码已经完成了,这时候已经是一个底层STL的红黑树了,已经已符合库里面的要求了,这时候我们是需要给他穿上对应的“衣服”,比如穿上set的“衣服”,那么这个穿上set的“衣服”,那么他就符合库里面set的要求了,同样map一样,这时候我们就需要实现set与map了。因此,上层容器map需要向底层红黑树提供一个仿函数,用于获取T当中的键值Key,这样一来,当底层红黑树当中需要比较两个结点的键值时,就可以通过这个仿函数来获取T当中的键值了。我们就可以使用仿函数了。
75 0
|
6月前
|
存储 编译器 容器
set、map、multiset、multimap的介绍及使用以及区别,注意事项
set是按照一定次序存储元素的容器,使用set的迭代器遍历set中的元素,可以得到有序序列。set当中存储元素的value都是唯一的,不可以重复,因此可以使用set进行去重。set默认是升序的,但是其内部默认不是按照大于比较,而是按照小于比较。set中的元素不能被修改,因为set在底层是用二叉搜索树来实现的,若是对二叉搜索树当中某个结点的值进行了修改,那么这棵树将不再是二叉搜索树。
247 0
|
10月前
|
存储 缓存 C++
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
C++ 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C++ 的开发者来说,了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C++ 常用的容器,包括序列容器(`std::vector`、`std::array`、`std::list`、`std::deque`)、关联容器(`std::set`、`std::map`)和无序容器(`std::unordered_set`、`std::unordered_map`),全面解析它们的特点、用法
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
|
10月前
|
编译器 测试技术 计算机视觉
红黑树模拟封装map和set
红黑树模拟封装map和set
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
231 2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
Java 开发者
在Java的集合世界里,Set以其独特的特性脱颖而出,它通过“哈希魔法”和“红黑树防御”两大绝技
【10月更文挑战第13天】在Java的集合世界里,Set以其独特的特性脱颖而出。它通过“哈希魔法”和“红黑树防御”两大绝技,有效抵御重复元素的侵扰,确保集合的纯洁性和有序性。无论是“人海战术”还是“偷梁换柱”,Set都能从容应对,成为开发者手中不可或缺的利器。
109 6
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
233 2
|
6月前
|
安全 Java 数据库连接
让我们讲解一下 Map 集合遍历的方式
我是小假 期待与你的下一次相遇 ~
231 43
使用 entrySet 遍历 Map 类集合 KV
使用 entrySet 遍历 Map 类集合 KV