版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Reflection_/article/details/78927452
非二叉树的建立及其基本操作
树不只有二叉树还可以为一个结点连接2个以上的结点,在现实事件中比比皆是,这时有非二叉树的记录和操作具有必要性。而实现思路是将非二叉树转化为二叉树存储,而读取使用时,恢复到原来的结构,即时有一种可恢复的模式转换,使得对使用者虚拟,同时代码又可以复用二叉树的基本操作方法。
1. 图示演示 非二叉树 转换为 二叉树
树的括号法建立二叉树结构
“一棵不开花的树”
“兄弟相连”:将统一父母的结点相连(蓝色)
“离家出走”:如果不是大儿子(最左边的子结点),则断开与父亲的链接。应该出门自力更生。
“长兄为父”:旋转兄弟使得兄长(最左边的子节点),成为其他儿子的父节点,且用右指针
最后呈现出 ,左指针指向真正的子结点,而右指针指向兄弟(暂作称呼)。遍历也是基于这条规则。
2.代码(基于家族族实例):
#include <iostream>
using namespace std;
#include <string>
#include <stack>
typedef struct node
{
string name;
int floor;
struct node * rchild = NULL;
struct node * lchild = NULL;
}people;//结点
stack<char>charStack;//字符栈
stack<people*>peoplePtrStack;//结点栈
people * CreatMarvelTree();//创建树
void PreVisitTree(people *t);//先序遍历
void DestroyTree(people *t);//清除内存
void InInformation(people *p);//输入结点数据
//功能概述:创建 二叉树 来存储 树
//输入:字符串-括号法 ps:结点不可用‘^’标志----特殊用途
//输入示例: A(B(C),D(M,N),C) or 0(a(2),(d))
//功能详细,以二叉树存储非二叉树,左儿子为真儿子,右儿子为兄弟
//输出:根指针
people * CreatMarvelTree()
{
string x = "*";
string s;
cin >> s;
s = x + s;
int n = 1;
people *treeRoot = NULL;
for (int i = 0; i<(int)s.length(); i++)
{
if (s.at(i) == '*') charStack.push(s.at(i));
if (s.at(i) == '(') charStack.push(s.at(i));
if (isalpha(s.at(i)) || isdigit(s.at(i)))
{
people *p = new people;
InInformation(p);
if (charStack.top() == '(')
{
people *pre = peoplePtrStack.top();
p->floor=1+ pre->floor;
if (pre->lchild)
{
while (pre->rchild)
{
pre = pre->rchild;
}
pre->rchild = p;
}
else
{
pre->lchild = p;
}
}
else if (charStack.top() == '*')
{
p->floor=0;
peoplePtrStack.push(p);
treeRoot = p;
}
else
{
people *pre = peoplePtrStack.top();
p->floor=pre->floor;
pre->rchild = p;
}
peoplePtrStack.push(p);
charStack.push(s.at(i));
}
if (s.at(i) == ')')
{
while (charStack.top() != '(')
{
charStack.pop();
peoplePtrStack.pop();
}
charStack.pop();
}
}
return treeRoot;
}
void InInformation(people *p)
{
cout << " " << "请输入姓名: ";
cin >> p->name;
}
void PreVisitTree(people *t)//先序遍历输出名字
{
if (t)
{
printf("\t\t ");
for(int i=0;i<t->floor;i++)
printf(" ");
printf(">");
cout <<'['<< t->name<<']'<<endl;
PreVisitTree(t->lchild);
PreVisitTree(t->rchild);
}
return;
}
void DestroyTree(people *t)//清除内存
{
if (t)
{
DestroyTree(t->lchild);
DestroyTree(t->rchild);
delete(t);
}
}
int main()
{
people *T;
T = CreatMarvelTree();
PreVisitTree(T);
DestroyTree(T);
return 0;
}
ps:
- 栈辅助 字符串 转换 树的结构
- floor 记录辈分(层次) 帮助输出树型
- 同理于二叉树的括号输入法。
- 在制作家族管理系统时,发现这样的工作中文的还比较少。
2017.12.25