github源码指引:共享内存、数据结构与算法:平衡二叉树set的lower_bound

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。


        本篇专门讲解lower_bound的实现。

目录

一、STL的lower_bound和upper_bound是什么

二、二叉树有没有lower_bound

三、演示代码

3.1 定义数据

3.2 调用lower_bound

3.3 完整代码

3.3 运行结果


一、STL的lower_bound和upper_bound是什么

        lower_bound是STL的一个奇妙概念,非STL很少见到对应的东西。lower_bound和upper_bound与STL的区间概念对应,lower_bound是区间的左端点,upper_bound则是右端点。

        也就是[lower_bound,upper_bound)。

        lower_bound是==的第一个位置,upper_bound是>=的第一个位置,合起来刚好就是==的去区间。

二、二叉树有没有lower_bound

        二叉树当然有,但是set不一定有,set概念上只要求唯一,不要求有序。因为我这里用的就是二叉树,所以是可以有的。

三、演示代码

3.1 定义数据

        为了支持部分查找,需要定义多个比较函数:

	struct DemoData : public CActiveObjectBase
	{
		typedef DemoData T_ME;
		long a = 0;
		long b = 0;
		long c = 0;
		sstring<8> s;

		//用于需要排序的场合
		bool operator < (T_ME const& tmp)const 
		{
			return a == tmp.a ? (b == tmp.b ? c < tmp.c : b < tmp.b) : a < tmp.a;
		}
		//部分比较函数
		static bool Less_A(T_ME const& tmp1, T_ME const& tmp2)
		{
			return tmp1.a < tmp2.a;
		}
		//某些场合也需要等于
		bool operator == (T_ME const& tmp)const { return !(*this<tmp) && !(tmp<*this); }

		friend ostream& operator << (ostream& o, T_ME const& d)
		{
			return o << d.a << " " << d.b << " " << d.c << " " << d.s.c_str();
		}
		//关键字的hash值,用于分块场合,应保证hash值的最后一部分仍然是平均分布的
		long keyhash()const { return a; }

		//用于输出数据的场合
		string& toString(string& str)const
		{
			char buf[2048];
			sprintf(buf, "%ld %ld %ld %s", a, b, c, s.c_str());
			return str = buf;
		}
		//用于表格输出
		static bool AddTableColumns(CHtmlDoc::CHtmlTable2& table)
		{
			table.AddCol("A", CHtmlDoc::CHtmlDoc_DATACLASS_RIGHT);
			table.AddCol("B", CHtmlDoc::CHtmlDoc_DATACLASS_RIGHT);
			table.AddCol("C", CHtmlDoc::CHtmlDoc_DATACLASS_RIGHT);
			table.AddCol("S", CHtmlDoc::CHtmlDoc_DATACLASS_RIGHT);
			return true;
		}
		bool AddTableData(CHtmlDoc::CHtmlTable2& table)const
		{
			table.AddData(a);
			table.AddData(b);
			table.AddData(c);
			table.AddData(s.c_str());
			return true;
		}
	};

        完整比较为a\b\c,额外定义了一个值比较a的:

//部分比较函数
		static bool Less_A(T_ME const& tmp1, T_ME const& tmp2)
		{
			return tmp1.a < tmp2.a;
		}

3.2 调用lower_bound

        调用时需要传入比较函数,比较函数可以是独立函数也可以是函数对象:

			DemoData tmp;
			tmp.a = i;
			T_CONTINER::const_iterator it_from = a.lower_bound(tmp, DemoData::Less_A);
			T_CONTINER::const_iterator it_to = a.upper_bound(tmp, DemoData::Less_A);

3.3 完整代码

class CTest_T_SHMSET_lower_bound
{
public:
	struct DemoData : public CActiveObjectBase
	{
		typedef DemoData T_ME;
		long a = 0;
		long b = 0;
		long c = 0;
		sstring<8> s;

		//用于需要排序的场合
		bool operator < (T_ME const& tmp)const 
		{
			return a == tmp.a ? (b == tmp.b ? c < tmp.c : b < tmp.b) : a < tmp.a;
		}
		//部分比较函数
		static bool Less_A(T_ME const& tmp1, T_ME const& tmp2)
		{
			return tmp1.a < tmp2.a;
		}
		//某些场合也需要等于
		bool operator == (T_ME const& tmp)const { return !(*this<tmp) && !(tmp<*this); }

		friend ostream& operator << (ostream& o, T_ME const& d)
		{
			return o << d.a << " " << d.b << " " << d.c << " " << d.s.c_str();
		}
		//关键字的hash值,用于分块场合,应保证hash值的最后一部分仍然是平均分布的
		long keyhash()const { return a; }

		//用于输出数据的场合
		string& toString(string& str)const
		{
			char buf[2048];
			sprintf(buf, "%ld %ld %ld %s", a, b, c, s.c_str());
			return str = buf;
		}
		//用于表格输出
		static bool AddTableColumns(CHtmlDoc::CHtmlTable2& table)
		{
			table.AddCol("A", CHtmlDoc::CHtmlDoc_DATACLASS_RIGHT);
			table.AddCol("B", CHtmlDoc::CHtmlDoc_DATACLASS_RIGHT);
			table.AddCol("C", CHtmlDoc::CHtmlDoc_DATACLASS_RIGHT);
			table.AddCol("S", CHtmlDoc::CHtmlDoc_DATACLASS_RIGHT);
			return true;
		}
		bool AddTableData(CHtmlDoc::CHtmlTable2& table)const
		{
			table.AddData(a);
			table.AddData(b);
			table.AddData(c);
			table.AddData(s.c_str());
			return true;
		}
	};
	typedef T_SHMSET<DemoData, PI_TEST_1, CDemoData > T_CONTINER;//迭代器和数据操作都是互斥的,但连接断开等管理类操作不是互斥的(通常也不应该并发操作)
	//typedef T_SHMSET_MUTEX<DemoData, PI_TEST_1, CDemoData > T_CONTINER;//用这个也可以,但只有M开头的操作才是互斥的,定义在shmSet.h,名字有点混乱
	static int test_T_SHMSET_lower_bound(int argc, char** argv)
	{
		T_CONTINER a("test", 1);
		a.DestoryShm();
		if (!a.CreateShm())return __LINE__;
		thelog << endi;
		if (!a.Attach(false))return __LINE__;
		thelog << endi;
		for (int i = 0; i < 10; ++i)
		{
			DemoData tmp;
			tmp.a = rand() % 2;
			tmp.b = rand() % 2;
			tmp.c = i;
			tmp.s = "abc";
			thelog << i << " n:" << tmp << " handle:" << a.insert(tmp).first.handle << endi;
		}
		for (T_CONTINER::const_iterator it = a.begin(); it != a.end(); ++it)
		{
			string str;
			thelog << it->toString(str) << endi;
		}
		for (int i = 0; i < 10; ++i)
		{
			DemoData tmp;
			tmp.a = i;
			T_CONTINER::const_iterator it_from = a.lower_bound(tmp, DemoData::Less_A);
			T_CONTINER::const_iterator it_to = a.upper_bound(tmp, DemoData::Less_A);
			string str;
			if (it_from != a.end())
			{
				thelog << "-----------------" << i << " 找到" << endi;
				for (T_CONTINER::const_iterator it = it_from; it != it_to; ++it)
				{
					thelog << it->toString(str) << endi;
				}
			}
			else thelog << "-----------------" << i << " 没找到" << endi;
		}
		a.RunCmdUI();

		return 0;
	}
};

3.3 运行结果

        命令23运行这个演示代码:

----------------------------------------
命令表:(q=exit)
0 管理
1 test_BinaryPool
3 test_CMultiProcessServer
4 test_CMultiProcessServer_view
5 test_CMultiProcessServer_speed
6 test_CMultiProcessServer_direct
7 test_RebuildSet
12 UDP测试客户端
13 UDP测试服务端
14 CStressTesting
15 CTestCSimpleMultiProcess_mutex atomic
16 CTest_hash
17 T_SHM_HASH
20 T_ARRAY
21 T_SHMSET_NO_MUTEX
22 T_SHMSET(带互斥)
23 T_SHMSET_lower_bound(带互斥)
88 test_CMyRWMutex
89 test_T_SHM_SET_GROUP
90 test_shm_IActiveObject
91 test_ShmMultiMap
99 test_ParseFromXml
........................................
----------------------------------------
请选择命令:(q=exit default=23):

[08-29 17:24:10][应用][信息] 用户输入的是:23
[08-29 17:24:10][应用][信息][shmEnv.cpp              : 718(GetSemReg)][  0.01]没有找到sem注册信息 default test 0
[08-29 17:24:10][应用][信息][shmEnv.cpp              : 646(GetShmReg)][  0.01]共享内存注册信息不存在 default test 0
[08-29 17:24:10][应用][信息][shmArray.h              :1024(_DestoryShm)][  0.01]test 0 连接到共享内存失败
[08-29 17:24:10][应用][信息][shmEnv.cpp              : 646(GetShmReg)][  0.01]共享内存注册信息不存在 default test 0
[08-29 17:24:10][应用][信息][shmArray.h              :1024(_DestoryShm)][  0.01]test 0 连接到共享内存失败
[08-29 17:24:10][应用][信息][shmEnv.cpp              : 624(GetShmConfig)][  0.01]未配置 SHM_CONFIG default.test
[08-29 17:24:10][应用][信息][shmArray.h              :1074(_CreateShm)][  0.01]default test 0 未配置的最大记录数
[08-29 17:24:10][应用][信息][shmArray.h              :1076(_CreateShm)][  0.01]使用默认值 1024
[08-29 17:24:10][应用][信息][shmArray.h              : 395(_CreateShmIfNeed)][  0.01]创建新共享内存成功,id = 32769
[08-29 17:24:10][应用][信息][shmArray.h              :1129(_CreateShm)][  0.01]基础共享内存创建完成
[08-29 17:24:10][应用][信息][shmArray.h              : 960(AttachToShm)][  0.01]test 连接共享内存成功 PI_N 1 PART 0 shmid = 32769 p 0x7f98904d5000
[08-29 17:24:10][应用][信息][shmSet_NoMutex.h        :1414(set_CreateShm)][  0.01]数据结构构造成功
[08-29 17:24:10][应用][信息][shmSet_NoMutex.h        :1416(set_CreateShm)][  0.01]创建成功
[08-29 17:24:10][应用][信息][shmfctest2.h            : 300(test_T_SHMSET_lower_bound)][  0.01]
[08-29 17:24:10][应用][信息][shmArray.h              : 960(AttachToShm)][  0.01]test 连接共享内存成功 PI_N 1 PART 0 shmid = 32769 p 0x7f98904d5000
[08-29 17:24:10][应用][信息][shmfctest2.h            : 302(test_T_SHMSET_lower_bound)][  0.01]
[08-29 17:24:10][应用][信息][shmfctest2.h            : 310(test_T_SHMSET_lower_bound)][  0.01]0 n:1 0 0 abc handle:0
[08-29 17:24:10][应用][信息][shmfctest2.h            : 310(test_T_SHMSET_lower_bound)][  0.01]1 n:1 1 1 abc handle:1
[08-29 17:24:10][应用][信息][shmfctest2.h            : 310(test_T_SHMSET_lower_bound)][  0.01]2 n:1 1 2 abc handle:2
[08-29 17:24:10][应用][信息][shmfctest2.h            : 310(test_T_SHMSET_lower_bound)][  0.01]3 n:0 0 3 abc handle:3
[08-29 17:24:10][应用][信息][shmfctest2.h            : 310(test_T_SHMSET_lower_bound)][  0.01]4 n:1 1 4 abc handle:4
[08-29 17:24:10][应用][信息][shmfctest2.h            : 310(test_T_SHMSET_lower_bound)][  0.01]5 n:0 1 5 abc handle:5
[08-29 17:24:10][应用][信息][shmfctest2.h            : 310(test_T_SHMSET_lower_bound)][  0.01]6 n:0 1 6 abc handle:6
[08-29 17:24:10][应用][信息][shmfctest2.h            : 310(test_T_SHMSET_lower_bound)][  0.01]7 n:1 0 7 abc handle:7
[08-29 17:24:10][应用][信息][shmfctest2.h            : 310(test_T_SHMSET_lower_bound)][  0.01]8 n:0 0 8 abc handle:8
[08-29 17:24:10][应用][信息][shmfctest2.h            : 310(test_T_SHMSET_lower_bound)][  0.01]9 n:0 0 9 abc handle:9
[08-29 17:24:10][应用][信息][shmfctest2.h            : 315(test_T_SHMSET_lower_bound)][  0.01]0 0 3 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 315(test_T_SHMSET_lower_bound)][  0.01]0 0 8 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 315(test_T_SHMSET_lower_bound)][  0.01]0 0 9 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 315(test_T_SHMSET_lower_bound)][  0.01]0 1 5 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 315(test_T_SHMSET_lower_bound)][  0.01]0 1 6 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 315(test_T_SHMSET_lower_bound)][  0.01]1 0 0 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 315(test_T_SHMSET_lower_bound)][  0.01]1 0 7 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 315(test_T_SHMSET_lower_bound)][  0.01]1 1 1 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 315(test_T_SHMSET_lower_bound)][  0.01]1 1 2 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 315(test_T_SHMSET_lower_bound)][  0.01]1 1 4 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 326(test_T_SHMSET_lower_bound)][  0.01]-----------------0 找到
[08-29 17:24:10][应用][信息][shmfctest2.h            : 329(test_T_SHMSET_lower_bound)][  0.01]0 0 3 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 329(test_T_SHMSET_lower_bound)][  0.01]0 0 8 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 329(test_T_SHMSET_lower_bound)][  0.01]0 0 9 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 329(test_T_SHMSET_lower_bound)][  0.01]0 1 5 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 329(test_T_SHMSET_lower_bound)][  0.01]0 1 6 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 326(test_T_SHMSET_lower_bound)][  0.01]-----------------1 找到
[08-29 17:24:10][应用][信息][shmfctest2.h            : 329(test_T_SHMSET_lower_bound)][  0.01]1 0 0 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 329(test_T_SHMSET_lower_bound)][  0.01]1 0 7 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 329(test_T_SHMSET_lower_bound)][  0.01]1 1 1 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 329(test_T_SHMSET_lower_bound)][  0.01]1 1 2 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 329(test_T_SHMSET_lower_bound)][  0.01]1 1 4 abc
[08-29 17:24:10][应用][信息][shmfctest2.h            : 332(test_T_SHMSET_lower_bound)][  0.01]-----------------2 没找到
[08-29 17:24:10][应用][信息][shmfctest2.h            : 332(test_T_SHMSET_lower_bound)][  0.01]-----------------3 没找到
[08-29 17:24:10][应用][信息][shmfctest2.h            : 332(test_T_SHMSET_lower_bound)][  0.01]-----------------4 没找到
[08-29 17:24:10][应用][信息][shmfctest2.h            : 332(test_T_SHMSET_lower_bound)][  0.01]-----------------5 没找到
[08-29 17:24:10][应用][信息][shmfctest2.h            : 332(test_T_SHMSET_lower_bound)][  0.01]-----------------6 没找到
[08-29 17:24:10][应用][信息][shmfctest2.h            : 332(test_T_SHMSET_lower_bound)][  0.01]-----------------7 没找到
[08-29 17:24:10][应用][信息][shmfctest2.h            : 332(test_T_SHMSET_lower_bound)][  0.01]-----------------8 没找到
[08-29 17:24:10][应用][信息][shmfctest2.h            : 332(test_T_SHMSET_lower_bound)][  0.01]-----------------9 没找到
[08-29 17:24:10][应用][信息][shmIActiveObject.h      : 457(RunCmdUI)][  0.01]
test

b:返回上一层
1:创建 2:连接(只读) 3:连接(可写) 4:断开 5:禁用互斥 6:清除数据 7:创建私有 8:删除共享内存 9:显示 10:数据
11:从数据库加载 12:保存到数据库
21:从目录加载 22:保存到目录 23:导出为文本文件
31:从目录加载到私有内存 32:销毁私有内存
97:repair 98:check 99:ToDo 100:shell(q=exit ):

        根据代码,a的值只有两个:0或1,所以最后只有0和1能找到数据。

        最后可以用共享内存接口的命令9来查看数据:

[08-29 17:24:10][应用][信息][shmIActiveObject.h      : 457(RunCmdUI)][  0.01]
test

b:返回上一层
1:创建 2:连接(只读) 3:连接(可写) 4:断开 5:禁用互斥 6:清除数据 7:创建私有 8:删除共享内存 9:显示 10:数据
11:从数据库加载 12:保存到数据库
21:从目录加载 22:保存到目录 23:导出为文本文件
31:从目录加载到私有内存 32:销毁私有内存
97:repair 98:check 99:ToDo 100:shell(q=exit ):
9
[08-29 17:25:23][应用][信息] 用户输入的是:9
[08-29 17:25:23][应用][信息][shmSet_NoMutex.h        :2096(Report)][  0.01]
此结构为SET,使用率见下面信息(而不是后面的T_ARRAY信息)
SET信息:0x7f98904d5ac0 head 1,size 10(0.98%),free_head -1,begin 3,sizeof(T) 32
USER_HEAD信息:0
test 开始报告T_ARRAY......
pHead=0x7f98904d5000 pData=0x7f98904d5ae0 isPrivate=0 shmid=32769 sizeof(T)=64
GUID = 8AA20E2E-4891-4df1-A87E-E5A23CB8D076
sizeof short= 2 int= 4 long= 8    byteorder= 1
 0 =   2784  1 =     32  2 =     64  3 =      1  4 =    998  5 =    999
 6 =   1000
name=test part=0 capacity=1024,size=10(0.98%) bytes=68320
地址映射表: GET_PP_SET=0x7ffccc2e6100
分块数 1
0 : shm_id=32769 handle[0,1024) 容量=1024 连接信息: shm_id=32769 addr=0x7f98904d5ae0
--------------------------------------------
GUID = 8AA20E2E-4891-4df1-A87E-E5A23CB8D076
sizeof short= 2 int= 4 long= 8    byteorder= 1
 0 =   2784  1 =     32  2 =     64  3 =      1  4 =    998  5 =    999
 6 =   1000
i h  P  L  R  b d F uF | A B C   S
- - -- -- -- -- - - -- - - - - ---
0 3  8 -1 -1  0 0 0  0 | 0 0 3 abc
1 8  5  3  9  0 0 0  0 | 0 0 8 abc
2 9  8 -1 -1  0 0 0  0 | 0 0 9 abc
3 5  1  8  0  0 0 0  0 | 0 1 5 abc
4 6  0 -1 -1  0 0 0  0 | 0 1 6 abc
5 0  5  6  7  0 0 0  0 | 1 0 0 abc
6 7  0 -1 -1  0 0 0  0 | 1 0 7 abc
7 1 -1  5  2  1 0 0  0 | 1 1 1 abc
8 2  1 -1  4 -1 0 0  0 | 1 1 2 abc
9 4  2 -1 -1  0 0 0  0 | 1 1 4 abc
- - -- -- -- -- - - -- - - - - ---


[08-29 17:25:23][应用][信息][shmIActiveObject.h      : 457(RunCmdUI)][  0.01]
test

b:返回上一层

        注意第一列i是遍历顺序,也就是数据从小到大,数据列C才是原始顺序(因为设置的值是顺序号)。h是句柄,也就是数组位置,应该和原始顺序一致,P是父节点,L是左子树,R是右子树。


(这里是文档结束)

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值