【MyCpp_3】非二叉树的建立及其基本操作(括号法建立)

版权声明:本文为博主原创文章,未经博主允许不得转载。 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:

  1. 栈辅助 字符串 转换 树的结构
  2. floor 记录辈分(层次) 帮助输出树型
  3. 同理于二叉树的括号输入法。
  4. 在制作家族管理系统时,发现这样的工作中文的还比较少。

2017.12.25

猜你喜欢

转载自blog.csdn.net/Reflection_/article/details/78927452