zoukankan      html  css  js  c++  java
  • 1. 抽象数据型

    操作 解释
    Parent(n,T) 返回树T结点n的父亲
    LeftMostChild(n,T) 返回树T结点n的最左儿子
    RightSibling(n,T) 返回树T结点n的右兄弟
    Data(n,T) 返回树T结点n的DATA域的值
    CreateK(v,T1,...,Tk) 建立DATA为v并且有k个子树
    Root(T) 返回T的根结点

    2. 遍历

    • 先根遍历
      • 先访问根结点
      • 然后先根遍历T1
      • . . .
      • 最后先根遍历Tk
    • 中根遍历
      • 先中根遍历T1
      • 访问根结点
      • . . .
      • 中根遍历Tk
    • 后根遍历
      • 后根遍历T1
      • . . .
      • 后跟遍历Tk
      • 访问根结点

    image_1bd8tbmmq1lhg14d419r41crm1l9f9.png-8.4kB

    先根遍历代码

        //按先根顺序列出n及其所有后代的数据域的值
        void PreOrder(node n,TREE T)
        {
            node c;
            visit(Data(n,T));
            c = LeftMostChild(n,T);
            while(c != NULL)
            {
                PreOrder(c,T);
                c = RightSibling(c,T);
            }
        }
    

    3. 树的实现

    3.1 树的数组表示

    • 示意图

    image_1bd8tu27d1rno1t25mui8rg1sr2m.png-26.2kB

    • 代码实现
        struct node {
            int parent; //记录父亲
            char data;
        };
        
        typedef node TREE[11];
        
        TREE T;
        
    

    3.2 树的邻接表表示

    • 示意图

    image_1bd8u78b4vca1ni51i4snks11hp13.png-22.1kB

    • 代码实现
        typedef int node;
        struct celltype {
            node element;
            celltype *next;
        };
        
        typedef celltype * LIST;
        typedef celltype * position;
        
        struct TREE {
            LIST header[maxnodes];
            datatype data[maxnodes];
            node root;
        };
        
    

    3.3 树的左右链表示

    • 介绍

      每个结点都有3个域,一个是数据域,一个指向其最左子树,一个指向其右兄弟。

    • 示意图

    image_1bd8uipus1rr415s51eo144bk9d1g.png-27kB

    • 代码实现
        struct {
            datatype data;
            int leftchild;
            int rightsibling;
        } celltype[maxnodes];
        
        //若想快速得到parent,可以加入一个域,指向父亲
        
    

    4. 森林和二叉树

    这里我基本上是参考着这篇博客

    4.1 树转化为二叉树

    基本步骤

    • 加线:在所有兄弟结点之间加一条连线
    • 去线:除了最左汉子,删除结点与其它孩子的连线
    • 层次调整:进行顺时针选装(第一个孩子是结点的左孩子,兄弟旋转后变成其右孩子)

    image_1bd8vsm35a4m19ploff1oovslg1t.png-123.2kB

    4.2 森林转二叉树

    基本步骤

    • 把每一棵树转化为二叉树
    • 第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树的根结点的右孩子,用线连接

    image_1bd900k8mvf9ber1e5toi1c612a.png-110.4kB

    4.3 二叉树转树

    基本步骤

    • 加线:若某结点X的左孩子结点存在,则将这个左孩子的右孩子结点、右孩子的右孩子结点、右孩子的右孩子的右孩子结点...,都作为结点X的孩子。将结点X与这些右孩子结点用连线连起来
    • 去线:删除原二叉树中所有结点与其右孩子结点的连线
    • 层次调整

    image_1bd90662frhr1mf7c031bps1rb2n.png-115kB

    4.4 二叉树转森林

    基本步骤

    • 从根结点开始,若右孩子存在,则把右孩子结点的连线删除。再查看分离后的二叉树,若其根结点的右孩子存在,继续删除...
    • 把每棵分离的二叉树转为树

    image_1bd90cqauucv1q9pd31huo1v9o34.png-125.4kB

    4.5 代码实现

    
        #define MAX 100
    
        //定义树的结构
        struct Tree
        {
        	vector<Tree *> child;
        	char data;
        	Tree(){ child.clear();}
        };
        
        //定义森林,即多棵树
        typedef vector<Tree *> Forest;
        
        //定义二叉树的结构
        struct BTree
        {
        	BTree * lchild;
        	BTree * rchild;
        	char data;
        };
    
    
        //从文件里读入信息并且创建二叉树和树
        void Create_Forest(Forest & F,ifstream & in)
        {
        	string str;
        	Tree * ALL[MAX], *p = NULL;
        	int top,i,j = 0;
        	while(in >> str && str != "")
        	{
        		top = -1;
        		i = 0;
        		while(str[i] != '')
        		{
        			//遇到左括号,则层数加1,且下一个添加最左子树
        			if(str[i] == '(')
        			{
        				top ++;
        				ALL[top] = p;
        			}
        			//遇到右括号,则层数减1
        			else if(str[i] == ')')
        				top --;
        			//遇到逗号,且下一个添加右子树
        			else if(str[i] == ',')
        				;
        			else
        			{
        				p = new Tree;
        				p -> data = str[i];
        				if(static_cast<int>(F.size()) == j)
        					F.push_back(p);
        				else
        					ALL[top] ->child.push_back(p);
        			}
        			i ++;
        		}
        		j++;
        	}	
        }
        
        void Create_BTree(BTree * &B,ifstream & in)
        {
        	BTree *ALL[MAX],*p = NULL;
            bool judge;
        	string str;
        	in >> str;
            int top = -1, i = 0;
            B = NULL;//先将根节点置空
            while(str[i] != '')
            {
                //遇到左括号,则层数加1,且下一个添加左子树
                if(str[i] == '(')
                {
                    top ++;
                    ALL[top] = p;
                    judge = true;
                }
                //遇到右括号,则层数减1
                else if(str[i] == ')')
                    top --;
                //遇到逗号,且下一个添加右子树
                else if(str[i] == ',')
                    judge = false;
                else
                {
                    p = new BTree;
                    p -> data = str[i];
                    p -> lchild = NULL;
                    p -> rchild = NULL;
                    if(B == NULL)   
        				B = p;
                    else if(judge)
                        ALL[top] -> lchild = p;
                    else
                        ALL[top] -> rchild = p;
                }
                i ++;
            }
        }
        
        //将森林转化为二叉树
        BTree * Forest_to_BTree(Forest F)
        {
        	BTree *B = new BTree;
        	Tree * bt = F[0];
        	B ->data = F[0] ->data;
        	F.erase(F.begin());
        	Forest tmp;
        	for(int num = bt ->child.size(), i = 0;i < num;i++)
        		tmp.push_back(bt ->child[i]);
        	if (!tmp.empty()) B->lchild = Forest_to_BTree(tmp);
        	if (!F.empty()) B->rchild = Forest_to_BTree(F);
        	return B;
        }
        
        //将二叉树转化为一颗树
        Tree * BTree_to_Tree(BTree * B)
        {
        	Tree * T;
        	T = new Tree;
        	T ->data = B ->data;
        	BTree * tmp;
        	if(B ->lchild)
        	{
        		tmp = B ->lchild;
        		while(tmp)
        		{
        			T ->child.push_back(BTree_to_Tree(tmp));
        			tmp = tmp ->rchild;
        		}
        	}
        	return T;
        }
        
        //利用上面的算法进而将二叉树转化为森林
        Forest BTree_to_Forest(BTree * B)
        {
        	vector<BTree *> f;
        	Forest F;
        	Tree * tr;
        	BTree *tmp = B;
        	while(tmp)
        	{
        		f.push_back(tmp);
        		tmp = tmp ->rchild;
        	}	
        	for(int num = static_cast<int>(f.size()),j = 0;j < num; j++)
        	{
        		f[j] ->rchild = NULL;
        		tr = BTree_to_Tree(f[j]);
        		F.push_back(tr);
        	}
        	return F;
        }
    
    
  • 相关阅读:
    chrome——关于chrome浏览器的奇葩问题
    vscode——配置终端集成bash和cmd
    AndroidStudio——Android SDK
    Navicat——如何导出所有的查询数据
    mpvue——实现点击数组内的某一元素进行置顶(排序第一)操作
    TP5.x——开启跨域访问
    TP5.x——聊天列表查询
    MarkDowm——语法篇
    写一个整数四则运算的解析器——语法分析部分
    写一个整数四则运算的解析器——词法分析部分
  • 原文地址:https://www.cnblogs.com/vachester/p/6685576.html
Copyright © 2011-2022 走看看