github源码指引:共享内存、数据结构与算法:树形结构ListTree

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

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

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


        专题:共享内存、数据结构与算法_初级代码游戏的博客-CSDN博客

        本文讲解带有子项的链表。

一、介绍

        与上一篇介绍的单向链表相比,多了一个子项指针。可以理解为原来的链表是兄弟关系,子项指针则是父子关系,从而可以构建树形结构。

        节点结构如下:

		T_SHM_SIZE hNext;//-1:无;0-N,指向下个地址
		T_SHM_SIZE hChild;//-1:无;0-N,指向子数据
		T_DATA data;

        迭代器复杂一些:

			bool isEnd()const { return -1 == handle; }
			bool hasNext()const { return -1 != LIST_NODE::at(handle).hNext; }
			long getNext()const { return LIST_NODE::at(handle).hNext; }
			void setNext(T_SHM_SIZE h)const { LIST_NODE::at(handle).hNext = h; }
			void setChild(T_SHM_SIZE h)const { LIST_NODE::at(handle).hChild = h; }
			long getChild()const { return LIST_NODE::at(handle).hChild; }

        容器操作也复杂一些:

		//查找一个项,没找到返回false,h返回找到的位置或列表最后一个节点
		bool FindInList(iterator const & head, T_DATA const & data, iterator & it)const;
		//添加data到head,如果head是isEnd则添加到新列表并放置位置在h,如果已经存在则覆盖,如果head是isEnd则会被修改
		bool AddList(iterator & head, T_DATA const & data, iterator & it);
		//添加data到head,如果head是isEnd则添加到新列表并放置位置在h,如果已经存在则覆盖,如果head是isEnd则会被修改
		bool AddChild(iterator const & node, T_DATA const & data, iterator & it);
		//添加data到head的尾部,如果head是isEnd则添加到新列表并放置位置在head,不检查是否存在
		bool AddTail(iterator & head,T_DATA const & data);
		//删除子项
		bool DeleteChild(iterator const & node);
		//删除链表
		bool DeleteList(iterator const & head);
		//删除链表的一个项
		bool DeleteListOne(iterator & head,iterator const & toDelete);

二、演示代码

#include "shmMultiListTree.h"
class CTest_T_MULTI_LISTTREE
{
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_MULTI_LISTTREE T_CONTINER;
	static int test_T_MULTI_LISTTREE(int argc, char** argv)
	{
		T_CONTINER a("test", 1);
		a.getIShmActiveObject()->DestoryShm();
		if (!a.getIShmActiveObject()->CreateShm())return __LINE__;
		thelog << endi;
		if (!a.getIShmActiveObject()->Attach(false))return __LINE__;
		thelog << endi;

		string str;

		vector v_heads;
		for (int i = 0; i < 2; ++i)
		{
			T_CONTINER::iterator head;

			for (int j = 10; j < 12; ++j)
			{
				DemoData tmp2;
				tmp2.a = i;
				tmp2.b = j;

				T_CONTINER::iterator it2;
				if (!a.AddList(head, tmp2, it2))return __LINE__;
				thelog << "添加成功 " << head.handle << " " << it2.handle << " : " << tmp2.toString(str) << endi;
				if(10==j)v_heads.push_back(head);

				for (int k = 100; k < 102; ++k)
				{
					DemoData tmp3;
					tmp3.a = i;
					tmp3.b = j;
					tmp3.c = k;

					T_CONTINER::iterator it_child;
					if (!a.AddChild(it2, tmp3, it_child))return __LINE__;
					thelog << "添加成功 " << i << " " << j << " " << k << " : " << tmp3.toString(str) << endi;
				}
			}
		}
		for (vector::const_iterator it = v_heads.begin(); it != v_heads.end(); ++it)
		{
			str = "";
			thelog << (*it).handle << endl << a.ReportList((*it).handle, str) << endi;
		}

		a.getIShmActiveObject()->RunCmdUI();

		return 0;
	}
};

        这段代码构建了两个链表,每个链表有两个节点,每个节点有两个子数据。

三、运行结果

        rebuild.sh 编译,run.sh运行,命令26(初次运行要先创建主共享内存命令0-1):

[09-04 08:52:44][应用][信息][shmfctest2.h            : 583(test_T_MULTI_LISTTREE)][  0.00]0
   0:0 10 0
       1:0 10 100
       2:0 10 101
   3:0 11 0
       4:0 11 100
       5:0 11 101

[09-04 08:52:44][应用][信息][shmfctest2.h            : 583(test_T_MULTI_LISTTREE)][  0.00]6
   6:1 10 0
       7:1 10 100
       8:1 10 101
   9:1 11 0
      10:1 11 100
      11:1 11 101

         冒号前面是节点号。使用共享内存管理界面的命令9可以查看到具体结构:

 h NEXT CHILD | A  B   C S
-- ---- ----- - - -- --- -
 0    3     1 | 0 10   0
 1    2    -1 | 0 10 100
 2   -1    -1 | 0 10 101
 3   -1     4 | 0 11   0
 4    5    -1 | 0 11 100
 5   -1    -1 | 0 11 101
 6    9     7 | 1 10   0
 7    8    -1 | 1 10 100
 8   -1    -1 | 1 10 101
 9   -1    10 | 1 11   0
10   11    -1 | 1 11 100
11   -1    -1 | 1 11 101
-- ---- ----- - - -- --- -

        应该很容易看明白了。


(这里是文档结束)

你可能感兴趣的:(github源码指引,共享内存,数据结构与算法,github,共享内存,树,链表)