先序中序求解二叉树(使用二叉查找树原理)

    二叉树的先序中序序列确定,二叉树也就确认了,但还原二叉树确实有点麻烦,要不断的遍历中序序列。后来学习了二叉查找树,发现了一个很巧的办法。

    二叉查找树的特性是每个节点都有权值,其规律为左子节点小于父节点,右子节点大于父节点,其中序序列是有序的。如果我们把二叉树变成二叉查找树,就是要给每个子节点赋值,最简单的根据中序序列从0->赋值,现在我们来看看二叉查找树先序序列和二叉查找树的关系。以下树的中序序列为DBEGACF,附上权值为(D:0,B:1,E:2,G:3,A:4,C:5,F:6 )

  关于这个2插树先序为ABDEGCF,先序序列是先本身节点->左节点->有节点。细心发现二叉查找树的先序序列可以作为节点进入树的先后顺序(节点进入树的先后顺序可以有多个,不一定是先序序列),根据中序的赋值先序可以为4102356(与ABDEGCF相对应)也就是用这个序列来创建二叉查找树。接下来就不用我多说了。附上C#实现代码(PS:写算法不要用C#,坑)

  1 namespace Test
  2 {
  3     class Program
  4     {
  5         static void Main(string[] args)
  6         {
  7             string first = "ABDEGCF";           //先序
  8             string mid = "DBEGACF";             //中序
  9             DouBleTree doubletree = new DouBleTree(first,mid);
 10             Console.WriteLine(doubletree.FirstOrder());     //先序
 11             Console.WriteLine(doubletree.MidOrder());       //中序
 12             Console.WriteLine(doubletree.AfterOrder());     //后序
 13             Console.ReadLine();
 14         }
 15     }
 16     public class DouBleTree
 17     {
 18         /// <summary>
 19         ///
 20         /// </summary>
 21         /// <param name="first">先序</param>
 22         /// <param name="mid">中序</param>
 23         public DouBleTree(string first, string mid)
 24         {
 25             tlist = new List<T>();
 26             for (int i = 0; i < mid.Length; i++)        //  附加权值
 27             {
 28                 T t = new T
 29                 {
 30                     data = mid[i],
 31                     WeigthValue = i,
 32                 };
 33                 tlist.Add(t);
 34             }
 35             doubleTreeRoot = new DoubleTreePoint        //创建根节点
 36             {
 37                 data = first[0],
 38                 WeightValue = tlist.FirstOrDefault(n => n.data == first[0]).WeigthValue,
 39             };
 40             for (int i = 1; i < first.Length; i++)      //创建二叉树
 41             {
 42                 T t = tlist.FirstOrDefault(n => n.data == first[i]);
 43                 doubleTreeRoot = InsertPoint(doubleTreeRoot, t);
 44             }
 45         }
 46         private DoubleTreePoint doubleTreeRoot;                                     //二叉树根节点
 47         private List<T> tlist;                                                      //给中序队列附权值
 48         private DoubleTreePoint InsertPoint(DoubleTreePoint point  ,T t)            //插入节点
 49         {
 50             if (point == null)
 51             {
 52                 point = new DoubleTreePoint
 53                 {
 54                     data = t.data,
 55                     WeightValue = t.WeigthValue,
 56                 };
 57                 return point;
 58             }
 59             if (point.WeightValue > t.WeigthValue)
 60             {
 61                  point.left = InsertPoint(point.left, t);
 62             }
 63             else
 64             {
 65                  point.right = InsertPoint(point.right, t);
 66             }
 67             return point;
 68
 69         }
 70         public string FirstOrder()                      //返回先序队列
 71         {
 72             string str = "";
 73             First(doubleTreeRoot,ref str);
 74             return str;
 75         }
 76         private void First(DoubleTreePoint doubleTreePoint,ref string str)
 77         {
 78             if (doubleTreePoint == null) return;
 79             str += doubleTreePoint.data;
 80             First(doubleTreePoint.left,ref str);
 81             First(doubleTreePoint.right,ref str);
 82         }
 83         public string MidOrder()
 84         {
 85             string str = "";
 86             Mid(doubleTreeRoot, ref str);
 87             return str;
 88         }
 89         private void Mid(DoubleTreePoint doubleTreePoint,ref string str)
 90         {
 91             if (doubleTreePoint == null) return;
 92             Mid(doubleTreePoint.left,ref str);
 93             str += doubleTreePoint.data;
 94             Mid(doubleTreePoint.right,ref str);
 95         }
 96         public string AfterOrder()
 97         {
 98             string str = "";
 99             After(doubleTreeRoot,ref str);
100             return str;
101         }
102         private void After(DoubleTreePoint doubleTreePoint,ref string str)
103         {
104             if (doubleTreePoint == null) return;
105             After(doubleTreePoint.left,ref str);
106             After(doubleTreePoint.right,ref str);
107             str += doubleTreePoint.data;
108         }
109     }
110     public class DoubleTreePoint
111     {
112         public char data { get; set; }          //数据
113         public DoubleTreePoint left { get; set; }
114         public DoubleTreePoint right { get; set; }
115         public int WeightValue { get; set; }    //权值
116     }
117     public class T
118     {
119         public char data { get; set; }
120         public int WeigthValue { get; set; }
121     }
122 }

  

时间: 2024-10-29 19:05:51

先序中序求解二叉树(使用二叉查找树原理)的相关文章

20140510 二叉树的建立 先序 后序 中序 比较

#include<stdio.h> #include<malloc.h> typedef struct node { int data; struct node *lchild,*rchild; }; node * create()//先序建立二叉树,根左右 { int x=0; node *t; printf(" input data:"); scanf("%d",&x); if(x==0) t=NULL; else { t=(no

二叉树先序中序非递归算法

一直想要写的 二叉树 中序 先序 后序遍历算法 当年学习DS最虚的就是这个,因为非递归算法复杂,测试数据不好弄,只能一个一个手动插入.感觉明显比图的难,虽然大家都觉得图更难..... 递归的太简单了,就不写了.关键是非递归版本. 先序: 我自己的版本: void RootPreTraverse(Node* p) { Stack S; while(S not empty) { p=S.top(); S.pop(); Show(p); if(p->right!=null) S.push(p->ri

二叉树的先序-中序-后序遍历(一)-循环----绝对白痴好记的方法

接着上一篇 二叉树的先序-中序-后序遍历(一)-递归 的讲,这篇该循环遍历了. 之前一直没有找到好的方法来循环遍历树,以前我老认为有些递归的能做的东西很难换成循环实现. 后来看了一些别人写的代码,然后又问了朋友,才发现...哦,原来这样的啊,我可以自己弄个栈来维护一下. 想到了可以弄个栈以后,至少在我认为,把递归转成循环已经是可行的了,至于怎么实现,这几天在想(因为太笨,看人家的代码总看一半就不想看),今天找到了一个好用的方法,在这里分享一下. 算法的核心是:你看二叉树的时候心里怎么想的,程序就

先序+中序和中序+后序建树

思路:先序的第一个元素和后序的最后一个元素是当前子树的根,然后遍历中序序列,找到左右子树的分界线,递归建左子树和右子树. class Solution { public: /*由于是oj,这里假设给的序列是合法的,正常情况是需要判断不合法情况的 */ TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder,int instart,int inend,int poststart,int post

二叉树的先序/中序/后序/层次遍历

[简介] 树形结构是一类重要的非线性数据结构,其中以树和二叉树最为常用. 二叉树是每个结点最多有两个子树的有序树.通常子树的根被称作"左子树"(left subtree)和"右子树"(right subtree).二叉树常被用作二叉查找树和二叉堆或是二叉排序树.二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒.二叉树的第i层至多有2的 i -1次方个结点:深度为k的二叉树至多有2^(k) -1个结点:对任何一棵二叉树T,

二叉树的遍历方法之层序-先序-中序-后序遍历的简单讲解和代码示例

二叉树的基础性质及二叉树的建立参见前面两篇博文: http://blog.csdn.net/why850901938/article/details/51052936 http://blog.csdn.net/why850901938/article/details/51052156 首先为了讲解方便,我建立了如图所示的二叉树: 取名为:树A 1.何为层序遍历? 层序遍历就是按照二叉树的层次由上到下的进行遍历,每一层要求访问的顺序为从左到右: 以树A为例,层序遍历得到的结果为: 5 2 6 1

二叉树 的先序 中序、后序遍历、层次遍历以及树状打印等操作

#include <stdio.h> #include <stdlib.h> #define MAXSIZE 50 typedef struct Node { char data; struct Node *LChild; struct Node *RChild; }BiTNode,*BiTree; typedef struct { BiTree element[MAXSIZE]; int front; int rear; }SeqQueue; /*初始化队列*/ void Ini

二叉树先序 中序 后序遍历

#include<stdio.h> #include<stdlib.h> #include<string.h> int index=1; typedef char String[24]; String str; /*=============用于构造二叉树(存储的数据)===============*/ void StrAssign(String str,char *chars){ int i; for(i=1;i<=strlen(chars);i++) str[

二叉树的遍历:先序中序后序遍历的递归与非递归实现及层序遍历

对于一种数据结构而言,遍历是常见操作.二叉树是一种基本的数据结构,是一种每个节点的儿子数目都不多于2的树.二叉树的节点声明如下: 1 typedef struct TreeNode *PtrToNode; 2 typedef struct TreeNode *BinTree; 3 4 struct TreeNode 5 { 6 int Data; //为简单起见,不妨假设树节点的元素为int型 7 BinTree Left; 8 BinTree Right; 9 }; 二叉树的遍历主要有先序遍历