18、基于共享内存的树形结构(不是二叉树)

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

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

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


        这个结构就是一般的树控件结构,每个节点都可以有任意多个子节点,子节点又可以有无限多子节点。

目录

一、节点结构

二、头结构

三、主体代码


        这种结构存储到数据库一般是靠父子关系关联,但是在内存里就没必要,直接建立父子关系,不需要每次都搜索。

        共享内存也是内存嘛,性能是首要要考虑的,所以直接建立了树结构来支持。

一、节点结构

        存储结构:

	template<typename T_DATA >
	struct T_LISTTREE_NODE_STRUCT
	{
		T_SHM_SIZE hNext;//-1:无;0-N,指向下个地址
		T_SHM_SIZE hChild;//-1:无;0-N,指向子数据
		T_DATA data;
		
		T_LISTTREE_NODE_STRUCT():hNext(-1), hChild(-1){}
		string & toString(string & str)const
		{
			char buf[2048];
			string tmp;
			sprintf(buf, "%8ld %8ld: %s", hNext, hChild, data.toString(tmp).c_str());
			return str=buf;
		}
		static bool AddTableColumns(CHtmlDoc::CHtmlTable2 & table)
		{
			table.AddCol("NEXT", CHtmlDoc::CHtmlDoc_DATACLASS_RIGHT);
			table.AddCol("CHILD", CHtmlDoc::CHtmlDoc_DATACLASS_RIGHT);
			table.AddCol("|");
			return T_DATA::AddTableColumns(table);
		}
		bool AddTableData(CHtmlDoc::CHtmlTable2 & table)const
		{
			table.AddData(hNext);
			table.AddData(hChild);
			table.AddData("|");
			return data.AddTableData(table);
		}
	};

        跟上一篇介绍的链表相比多了子节点链表。

        对象结构:

	template<typename T_DATA,int PI_N,typename T_HANDLE >
	struct T_LISTTREE_NODE : public T_LISTTREE_NODE_STRUCT<T_DATA >
	{
		static T_LISTTREE_NODE & at(T_SHM_SIZE n)
		{
			if(n<0)
			{
				G_SET_ERROR(My_ERR_INVALID_HANDLE);
				thelog<<"at error "<<n<<ende;
			}
			T_HANDLE array_handle(n);
			//char buf[256];
			//sprintf(buf,"%ld %p",n,&*array_handle);
			//theLog<<buf<<endi;
			return *(T_LISTTREE_NODE *)(void *)&*array_handle;
		}
		T_SHM_SIZE _me()const
		{
			return T_HANDLE::_me(this);
		}
	};

二、头结构

	template<typename T_USER_HEAD>
	struct T_LISTTREE_HEAD
	{
		T_SHM_SIZE free_size;//节点个数
		T_SHM_SIZE free_head;//空闲地址头指针

		T_USER_HEAD user_head;//用户的特殊数据

		T_LISTTREE_HEAD() :free_size(0), free_head(-1){}
		
		string & toString(string & str)const
		{
			char buf[2048];
			string tmp;
			sprintf(buf,"free_size=%ld free_head=%ld ",free_size,free_head);
			str = buf + user_head.toString(tmp);
			return str;
		}
	};

三、主体代码

	template<typename T_DATA,int PI_N,typename T_USER_HEAD = CDemoData,int PART=0,typename T_HANDLE=T_HANDLE_ARRAY<T_LISTTREE_NODE_STRUCT<T_DATA>,PI_N > >
	class T_MULTI_LISTTREE : public T_ARRAY<T_LISTTREE_NODE_STRUCT<T_DATA>, PI_N, T_LISTTREE_HEAD<T_USER_HEAD>, PART, T_HANDLE >
	{
	private:
		typedef T_ARRAY<T_LISTTREE_NODE_STRUCT<T_DATA>, PI_N, T_LISTTREE_HEAD<T_USER_HEAD>, PART, T_HANDLE > T_PARENT;
	public:
		typedef T_LISTTREE_HEAD<T_USER_HEAD> LIST_HEAD;
		typedef T_LISTTREE_NODE<T_DATA,PI_N,T_HANDLE > LIST_NODE;
		using T_PARENT::Add;
		struct iterator
		{
			T_SHM_SIZE handle;

			iterator():handle(-1){}
			bool operator == (iterator const & tmp)const{return handle==tmp.handle;}
			bool operator != (iterator const & tmp)const{return !(*this==tmp);}
			T_DATA & operator * ()const
			{
				return LIST_NODE::at(handle).data;
			}
			T_DATA * operator -> ()const
			{
				return &(operator *());
			}
			iterator & operator ++ ()
			{
				handle=LIST_NODE::at(handle).hNext;
				return *this;
			}
			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; }
		};
		typedef iterator const_iterator;
	public:
		T_MULTI_LISTTREE(char const * name, int version) :T_PARENT(name, version){}
		T_USER_HEAD * GetUserHead(){return &T_PARENT::GetUserHead()->user_head;}
		LIST_HEAD * GetListHead()const{return T_PARENT::GetUserHead();}
		bool Reserve(T_SHM_SIZE _n){ return T_PARENT::Reserve(_n); }
		//查找一个项,没找到返回false,h返回找到的位置或列表最后一个节点
		bool FindInList(iterator const & head, T_DATA const & data, iterator & it)const
		{
			it = head;
			while (!it.isEnd())
			{
				if (!(data < *it) && !(*it < data))return true;
				if (!it.hasNext())break;
				++it;
			}
			return false;
		}
		//添加data到head,如果head是isEnd则添加到新列表并放置位置在h,如果已经存在则覆盖,如果head是isEnd则会被修改
		bool AddList(iterator & head, T_DATA const & data, iterator & it)
		{
			if (FindInList(head, data, it))
			{
				*it = data;
				return true;
			}
			T_HANDLE h;
			if (-1 != GetListHead()->free_head)
			{
				h = GetListHead()->free_head;
				GetListHead()->free_head = h->hNext;
				--GetListHead()->free_size;

				h->data = data;
				h->hNext = -1;
			}
			else
			{
				LIST_NODE tmp;
				tmp.data = data;
				if (!Add(tmp, h))
				{
					thelog << "mutlilist add error" << ende;
					return false;
				}
			}
			//仅当head是isEnd此时it才会是isEnd
			if (it.isEnd())
			{
				it.handle = h.handle;
				head.handle = h.handle;
			}
			else
			{
				it.setNext(h.handle);
				++it;
			}
			return true;
		}
		//添加data到head,如果head是isEnd则添加到新列表并放置位置在h,如果已经存在则覆盖,如果head是isEnd则会被修改
		bool AddChild(iterator const & node, T_DATA const & data, iterator & it)
		{
			if (node.isEnd())return false;
			iterator head;
			head.handle = node.getChild();
			if (AddList(head, data, it))
			{
				node.setChild(head.handle);
				return true;
			}
			return false;
		}
		//添加data到head的尾部,如果head是isEnd则添加到新列表并放置位置在head,不检查是否存在
		bool AddTail(iterator & head,T_DATA const & data)
		{
			T_HANDLE h;
			if (-1 != GetListHead()->free_head)
			{
				h = GetListHead()->free_head;
				GetListHead()->free_head = h->hNext;
				--GetListHead()->free_size;
				
				h->data = data;
				h->hNext = -1;
			}
			else
			{
				LIST_NODE tmp;
				tmp.data = data;
				if (!Add(tmp, h))
				{
					thelog << "mutlilist add error" << ende;
					return false;
				}
			}
			if(head.isEnd())
			{
				head.handle=h.handle;
			}
			else
			{
				T_HANDLE tmph;
				tmph.handle=head.handle;
				while(-1!=tmph->hNext)
				{
					tmph=tmph->hNext;
				}
				tmph->hNext=h.handle;
			}
			return true;
		}
		//删除子项
		bool DeleteChild(iterator const & node)
		{
			if (node.isEnd())return true;

			iterator it;
			it.handle = node.getChild();
			if (it.isEnd())return true;
			if (DeleteList(it))
			{
				node.setChild(-1);
				return true;
			}
			return false;
		}
		//删除链表
		bool DeleteList(iterator const & head)
		{
			if (head.isEnd())return true;
			T_HANDLE tmph;
			long count = 0;
			tmph.handle = head.handle;
			while(-1!=tmph.handle)
			{
				++count;
				iterator node;
				node.handle = tmph.handle;
				DeleteChild(node);
				if (-1 == tmph->hNext)break;
				tmph = tmph->hNext;
			};
			tmph->hNext = GetListHead()->free_head;
			GetListHead()->free_head = head.handle;
			GetListHead()->free_size += count;
			return true;
		}
		//删除链表的一个项
		bool DeleteListOne(iterator & head,iterator const & toDelete)
		{
			//thelog<<head.handle<<" "<<toDelete.handle<<endi;
			if (head.isEnd())
			{
				thelog<<"无效的头"<<ende;
				return false;
			}
			T_HANDLE tmph,tmpDelete;
			tmph.handle = head.handle;
			tmpDelete.handle = toDelete.handle;
			if (toDelete == head)
			{
				DeleteChild(toDelete);
				//thelog<<"删除头"<<endi;
				head.handle = tmpDelete->hNext;//修改头
				tmpDelete->hNext = GetListHead()->free_head;//放在空闲头处
				GetListHead()->free_head = tmpDelete.handle;
				++GetListHead()->free_size;
				return true;
			}
			else
			{
				while (-1 != tmph->hNext)
				{
					if (tmpDelete.handle == tmph->hNext)
					{
						DeleteChild(toDelete);
						//thelog << "删除非头" << endi;
						tmph->hNext = tmpDelete->hNext;//卸下要删除的节点
						tmpDelete->hNext = GetListHead()->free_head;//放在空闲头处
						GetListHead()->free_head = tmpDelete.handle;
						++GetListHead()->free_size;
						return true;
					}
					else
					{
						tmph = tmph->hNext;
					}
				}
			}
			thelog<<"没找到"<<ende;
			return false;
		}
		string & _ReportList(long h, string & ret, long level)const
		{
			string px;
			long i;
			for (i = 0; i < level; ++i)px += "    ";

			iterator it;
			it.handle = h;
			while (!it.isEnd())
			{
				string str;
				ret += px + it->toString(str) + "\n";
				_ReportList(it.getChild(), ret, level + 1);
				++it;
			}
			return ret;
		}
		string & ReportList(long h, string & ret)const
		{
			return _ReportList(h, ret, 0);
		}
	public:
		IShmActiveObject * getIShmActiveObject(){ return this; }
		//IShmActiveObject接口
		virtual bool Report()const
		{
			string str;
			thelog << endl << T_PARENT::Report(str, true) << endi;
			return true;
		}
	};

        其实一点也不复杂。


(这里是结束)

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值