树和二叉树及C#实现

树的相关术语

  • 结点:
    包括一个数据元素及若干指向其他结点的分支信息
  • 结点的度
    一个结点的子树个数称为此结点的度。
  • 叶结点
    度为0的结点,即无后继的结点,也称为终端结点
  • 分支结点
    度不为0的结点,也称为非终端结点
  • 结点的层次
    从根结点开始定义,根节点的层次为1,根的直接后继层次为2,依此类推。
  • 结点的层次编号
    将树中的结点按从上层到下层、同层从左到右的次序排成一个线性序列,依次给它们编以连续的自然数。
  • 树的度
    树中所有结点大的度的最大值
    二叉树结点的度数指该结点所含子树的个数。
  • 树的高度(深度):
    树中所有结点的层次的最大值。
    二叉树的深度是指所有结点中最深的结点所在的层数。
  • 有序树
    在数T中,如果各子树Ti之间是有先后次序的,则称为有序树。
  • 森林
    m(m>=0)棵互不相交的树的集合。将一棵非空树的根节点删去,树就变成一个森林,反之,给森林增加一个统一的跟结点,森林就变成一棵树。
  • 同构
    对两颗树,通过对结点适当地重命名,就可以使两棵树完全相等(结点对应相等,对应结点的相关关系也相等),则称这两棵树同构。
  • 孩子结点
    一个结点的直接后继结点称为该结点的孩子结点。
  • 双亲结点
    一个结点的直接前驱结点称为该结点的双亲结点。
  • 兄弟结点
    同一双亲结点的孩子结点之间互称兄弟结点。
  • 堂兄弟
    父亲是兄弟关系或堂兄弟关系的结点称为堂兄弟结点。
  • 祖先结点
    一个结点的祖先结点是指从跟结点到该结点的路径上的所有结点。
  • 子孙结点
    一个积极点的直接后继和间接后继称为该结点的子孙结点。
  • 前辈
    层号比该结点小的结点,都称为该结点的前辈。
  • 后辈
    层号比该结点小的结点,都称为该结点的后辈。

二叉树

把满足一下两个条件的树型结构叫做二叉数。

  1. 每个节点的度都不大于2;
  2. 每个节点的孩子节点次序不能任意颠倒

二叉树的性质

  • 性质1:
    在二叉树的第i层上至多有2^(i+1)个结点(i>=1)。

  • 性质2:
    深度为k的二叉树至多有2^k-1个结点(K>=1)。

  • 性质3:
    对任意一棵二叉树T,若终端结点数为n0,而且度数为2的结点数为n2,则n0=n2+1

  • 满二叉树:
    深度为k且有2^k-1个结点的二叉树。在满二叉树中,每层结点都是满的,即每层结点都具有最大结点数。

  • 完全二叉树:
    深度为k,结点为n的二叉树,如果其结点1n的位置序号分别与满二叉树的结点1n的位置序号一一对应,则完全为二叉树。

    TIM截图20181210174810.png

  • 性质4:
    具有n个结点的完全二叉树的深度为[log2n]+1

  • 性质5:
    对于具有n个结点的完全二叉树,如果按照从上到下和从左到右的顺序对二叉树中的所有结点从1开始顺序编号,则对于任意的序号为i的结点有:
    (1)如i=1,则序号为i的结点是根结点,无双亲结点;如i>1,则序号为i的结点的双亲结点序号为[i/2]。
    (2)如2i>n,则序号为i的结点无左孩子;如2xi<=n,则序号为i的结点的左孩子结点的序号为2i。
    (3)如2i+1>n,则序号为i的结点无右孩子;如2i+1<=n,则序号为i的结点的右孩子结点的序号为2*i+1。

二叉树的遍历

二叉树的遍历有6中方式:
(1)访问根,遍历左子树,遍历右子树(记做DLR)。
(2)访问根,遍历右子树,遍历左子树(记做DRL)。
(3)遍历左子树,访问根,遍历右子树(记做LDR)。
(4)遍历左子树,遍历右子树,访问根(记做LRD)。
(5)遍历右子树,访问根,遍历左子树(记做RDL)。
(6)遍历右子树,遍历左子树,访问根(记做RLD)。
在以上6中方式中,如果规定按先左后右的顺序,那么就只剩DLR、LDR和LRD三种。
下面就分别介绍三种遍历方法的递归定义。
(1)先序遍历(DLR)操作过程若二叉树为空,则空操作,否则依次执行如下3个操作:
①访问根结点;
②按先序遍历左子树;③按先序遍历右子树。
(2)中序遍历(LDR)操作过程若二叉树为空,则空操作,否则依次执行如下3个操作:
①按中序遍历左子树;
②访问根结点;
③按中序遍历右子树。
(3)后序遍历(LRD)操作过程若二叉树为空,则空操作,否则依次执行如下3个操作:
①按后序遍历左子树;②按后序遍历右子树;
③访问根结点。
显然,遍历操作是一个递归过程。

三种遍历的实现

TreeNode

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tree
{
    class TreeNode<T>
    {
        T data;
        TreeNode<T> LChrild;
        TreeNode<T> RChirld;
        
        public T Data { get => data; set => data = value; }
        internal TreeNode<T> LChrild1 { get => LChrild; set => LChrild = value; }
        internal TreeNode<T> RChirld1 { get => RChirld; set => RChirld = value; }

        public TreeNode(T data)
        {
            this.Data = data;
        }
    }
}

Program

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tree
{
    class Program
    {
        static void Main(string[] args)
        {
            TreeNode<string> root = new TreeNode<string>("a");
            TreeNode<string> L = new TreeNode<string>("b");
            TreeNode<string> R = new TreeNode<string>("c");
            root.LChrild1 = L;
            root.RChirld1 = R;
            DLR(root);
            Console.WriteLine("----");
            LDR(root);
            Console.WriteLine("----");
            LRD(root);
        }

        /// <summary>
        /// 先序遍历
        /// </summary>
        /// <param name="root"></param>
        static void DLR(TreeNode<string> root)
        {
            if (root != null)
            {
                Console.WriteLine(root.Data);
                DLR(root.LChrild1);
                DLR(root.RChirld1);
            }
        }

        /// <summary>
        /// 中序遍历
        /// </summary>
        /// <param name="root"></param>
        static void LDR(TreeNode<string> root)
        {
            if (root != null)
            {
                LDR(root.LChrild1);
                Console.WriteLine(root.Data);
                LDR(root.RChirld1);
            }
        }

        /// <summary>
        /// 后序遍历
        /// </summary>
        static void LRD(TreeNode<string> root)
        {
            if (root != null)
            {
                LRD(root.LChrild1);
                LRD(root.RChirld1);
                Console.WriteLine(root.Data);
            }
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容