c++实现多叉树树形显示(适合家谱的显示)

多叉树(左兄弟右孩子二叉树)的树形显示

核心代码

 

void positionadd(Multiway_tree*root, int n)
{
	if (!root)return;
	Multiway_tree*pcur = root;
	stack<Multiway_tree*>s;
	while (pcur || !s.empty())
	{
		if (pcur)
		{
			if (pcur == root->brother)break;
			pcur->positon += n;
			s.push(pcur);
			pcur = pcur->child;
		}
		else
		{
			pcur = s.top();
			s.pop();
			pcur = pcur->brother;
		}
	}
}
void Multiway_tree::display(Multiway_tree *root, const int distance)
{

	if (root == NULL)
	return;

	root->positon = 0;
	root->positionmark = " ";
	int *namenum = new int[sum];
	stack<Multiway_tree*>s;
	Multiway_tree *pcur;
	pcur = root;
	int gener = 0;
	
	while (pcur || !s.empty())
	{
		if (pcur)
		{
			if (pcur->generation > gener)gener = pcur->generation;
			if (gener)
				s.push(pcur);
			pcur = pcur->child;
		}
		else
		{
			pcur = s.top();
			s.pop();
			pcur = pcur->brother;
		}
	}
	

	Multiway_tree **p1 = new Multiway_tree*[gener + 1];

	for (int i = 0; i < gener + 1; ++i)
		p1[i] = 0;
	pcur = root;
	while (pcur || !s.empty())
	{
		if (pcur)
		{

			if (!(p1[pcur->generation]))p1[pcur->generation] = pcur;
			else { Multiway_tree*t = p1[pcur->generation]; while (t->next)t = t->next; t->next = pcur; }
			
			namenum[pcur->num] = pcur->name.size() ;

			if (pcur->parent)
				if (pcur->parent->child == pcur)
				{
					Multiway_tree*t = pcur;
					if (pcur->brother)pcur->positionmark = "/";
					else pcur->positionmark = "|";
					t->parent->childrennum++;
					while (t->brother)
					{
						t->parent->childrennum++;
						t->brother->positionmark = "|";
						t = t->brother;
					}
					if (t != pcur)t->positionmark = "\\";
				}

			s.push(pcur);
			pcur = pcur->child;
		}
		else
		{
			pcur = s.top();
			s.pop();
			pcur = pcur->brother;
		}
	}

	pcur = root;
	pcur->positon = 0;
	while (pcur || !s.empty())
	{
		if (pcur)
		{
			if (pcur->parent)
			{
				int n = 0;
				if (pcur->parent->child == pcur)
				{
					Multiway_tree*t = pcur;
					pcur->positon = 0;
					while (t->brother)
					{
						t->brother->positon = t->positon + namenum[t->num] + distance;
						t = t->brother;
					}

					int g = t->parent->positon + (namenum[t->parent->num]) / 2 - (t->positon + namenum[t->num]) / 2;

					if (t->parent->childrennum == 1)pcur->positon = pcur->parent->positon + namenum[pcur->parent->num] / 2 - namenum[pcur->num] / 2;
					else pcur->positon = g;
					t = pcur;
					while (t->brother)
					{
						t->brother->positon += g;
						t = t->brother;
					}

				}

			}
			s.push(pcur);
			pcur = pcur->child;
		}
		else
		{
			pcur = s.top();
			s.pop();
			pcur = pcur->brother;
		}
	}
	for (int i = gener; i > 0; --i)
	{

		for (Multiway_tree*t1 = p1[i]; t1->next; t1 = t1->next)
		{
			if (t1->parent->child != t1)continue;
			for (Multiway_tree*t2 = t1->next; t2; t2 = t2->next)
			{
				if (t2->parent == t1->parent)continue;
				else
				{
					Multiway_tree*t1n = t1;
					while (t1n->brother)t1n = t1n->brother;
					Multiway_tree*t2n = t2;
					while (t2n->brother)t2n = t2n->brother;
					if (!
						((t1->positon >= (t2n->positon + namenum[t2n->num])) || (t2->positon >= (t1n->positon + namenum[t1n->num])))
						)
					{
						int d = 0;
						abs(t1->parent->child->positon - t2n->positon - namenum[t2n->num]) > abs(t2->parent->child->positon - t1n->positon - namenum[t1n->num])
							? abs(t2->parent->child->positon - t1n->positon - namenum[t1n->num]) : abs(t1->parent->child->positon - t2n->positon - namenum[t2n->num]);


						Multiway_tree*t1p = t1, *t2p = t2;
						while (t1p->parent != t2p->parent)
						{

							t1p = t1p->parent; t2p = t2p->parent;

						}
						int n = 0;

						Multiway_tree*temp = t1p;

						for (temp = t1p, n = 0; temp != t2p && temp; temp = temp->brother)
							++n;
						if (temp != t2p)
						{
							for (temp = t2p, n = 0; temp != t1p && temp; temp = temp->brother)
								++n;
							d = abs(t1->parent->child->positon - t2n->positon - namenum[t2n->num]);
						}
						else {
							d = abs(t2->parent->child->positon - t1n->positon - namenum[t1n->num]);
						}

						//4???

						int averaged = (d + distance) / n + 1;


						if (t1p->parent->childrennum % 2 == 0)
						{
							int childn = 0;
							temp = t1p->parent->child;
							while (temp)
							{
								childn++;
								int t = averaged*(childn - t1p->parent->childrennum / 2) - averaged / 2;
								positionadd(temp, t);
								temp = temp->brother;

							}
						}

						else
						{

							int childn = 0;
							temp = t1p->parent->child;
							while (temp)
							{
								childn++;
								int t = averaged*(childn - (t1p->parent->childrennum + 1) / 2);

								positionadd(temp, t);

								temp = temp->brother;

							}


						}

					}



				}


			}

		}
	}

	int minposition = INT_MAX;
	pcur = root;
	while (pcur || !s.empty())
	{
		if (pcur)
		{


			if (minposition > pcur->positon)
				minposition = pcur->positon;

			s.push(pcur);
			pcur = pcur->child;
		}
		else
		{
			pcur = s.top();
			s.pop();
			pcur = pcur->brother;
		}
	}
	positionadd(root, -1 * minposition + 1);
	COORD info = GetLargestConsoleWindowSize(GetStdHandle(STD_OUTPUT_HANDLE));
	if (root->positon < info.X / 4);

	positionadd(root, info.X / 4 - root->positon);


	string *output = new string[(gener + 1) * 3];
	for (int i = 0; i < (gener + 1) * 3; ++i)
		output[i].append(119, ' ');
	for (int i = 1; i < gener + 1; ++i)
	{

		for (Multiway_tree *temp = p1[i]; temp; temp = temp->next)
		{
			string t = temp->name ;
			output[i].replace(temp->positon, namenum[temp->num], t);
			output[i + gener].replace(temp->positon + namenum[temp->num] / 2, 1, (temp->positionmark));

			output[i + gener * 2].replace(temp->positon + namenum[temp->num] / 2, to_string(temp->num).size(), to_string(temp->num));

		}
	}
	for (int i = 1; i < gener + 1; ++i)
	{

		cout << output[i + gener * 2] << endl << output[i] << endl << endl;
		if (i != gener)cout << output[i + 1 + gener] << endl << endl;
	}
	
}

  下载地址

 https://download.csdn.net/download/li_haoren/10336965

perorder.txt inorder.txt 分别是对本质的二叉树的前序和中序遍历保存的文件

posted @ 2018-03-27 20:54  ff_d  阅读(1538)  评论(0编辑  收藏  举报