zoukankan      html  css  js  c++  java
  • 线索二叉树

    1 namespace ThreadBinaryTree
    2 {
    3 public enum Tag
    4 {
    5 Link, Thread
    6 }
    7 public class BiThrNode
    8 {
    9 public int Data;
    10 public BiThrNode Lchild, Rchlid;
    11 public Tag LTag, RTag;
    12 public BiThrNode(int d)
    13 {
    14 Data = d;
    15 Lchild = null;
    16 Rchlid = null;
    17
    18 }
    19 }
    20 public class VisitClass
    21 {
    22 public delegate void Visit(int i);//委托
    23  
    24 public static void Display(int i)
    25 {
    26 Console.Write(i+" ");
    27 }
    28 }
    29 }

    1.中序线索化二叉树以及中序遍历线索二叉树

    1 namespace ThreadBinaryTree
    2 {
    3
    4 class InOrderThread
    5 {
    6 //静态变量 _pre保存当前结点的前驱
    7   static BiThrNode _pre;
    8
    9
    10 /// <summary>
    11 /// 二叉树中序线索化
    12 /// </summary>
    13 /// <param name="node"></param>
    14   public static void InThreading(BiThrNode node)
    15 {
    16 if (node != null)
    17 {
    18 InThreading(node.Lchild);
    19 if (node.Lchild == null)
    20 {
    21 node.LTag = Tag.Thread; // 前驱线索
    22   node.Lchild = _pre; // 左孩子指针指向前驱
    23   }
    24 if (_pre.Rchlid == null) // 前驱没有右孩子
    25   {
    26 _pre.RTag = Tag.Thread; // 后继线索
    27   _pre.Rchlid = node; // 前驱右孩子指针指向后继(当前结点p)
    28   }
    29 _pre = node; // 保持pre指向p的前驱
    30   InThreading(node.Rchlid);
    31 }
    32 }
    33 /// <summary>
    34 /// 为线索二叉树增加一个头结点,作为最左边结点前驱和最右边结点后继
    35 /// </summary>
    36 /// <param name="node"></param>
    37 /// <returns></returns>
    38   public static BiThrNode InOrderThreading(BiThrNode node)
    39 {
    40 BiThrNode head=new BiThrNode(0);
    41 head.LTag = Tag.Link; // 建头结点
    42 head.RTag = Tag.Thread;
    43 head.Rchlid = head; // 右指针回指
    44 if (node==null)
    45 {
    46 head.Lchild = head;
    47 }
    48 else
    49 {
    50 head.Lchild = node;
    51 _pre = head;
    52 InThreading(node); // 中序遍历进行中序线索化
    53 _pre.Rchlid = head;
    54 _pre.RTag = Tag.Thread; // 最后一个结点线索化
    55 head.Rchlid = _pre;
    56 }
    57
    58 return head;
    59 }
    60 /// <summary>
    61 ///中序遍历线索二叉树,通过后继
    62 /// </summary>
    63 /// <param name="node"></param>
    64 /// <param name="v"></param>
    65 public static void InOrderTraverseThrPost(BiThrNode node, VisitClass.Visit v)
    66 {
    67 BiThrNode p;
    68 p = node.Lchild; // p指向根结点
    69 while (p != node)
    70 { // 空树或遍历结束时,p==node
    71 while (p.LTag == Tag.Link)
    72 p = p.Lchild;
    73 v(p.Data);// 访问其左子树为空的结点
    74
    75 while (p.RTag == Tag.Thread && p.Rchlid != node)
    76 {
    77 p = p.Rchlid;
    78 v(p.Data); // 访问后继结点
    79 }
    80 p = p.Rchlid;
    81 }
    82 }
    83 /// <summary>
    84 ///中序遍历线索二叉树,通过前驱
    85 /// </summary>
    86 /// <param name="node"></param>
    87 /// <param name="v"></param>
    88 public static void InOrderTraverseThrPre(BiThrNode node, VisitClass.Visit v)
    89 {
    90 BiThrNode p;
    91 p = node.Lchild; // p指向根结点
    92 while (p != node)
    93 { // 空树或遍历结束时,p==node
    94 while (p.RTag == Tag.Link)
    95 p = p.Rchlid;
    96 v(p.Data);// 访问其左子树为空的结点
    97
    98 while (p.LTag == Tag.Thread && p.Lchild != node)
    99 {
    100 p = p.Lchild;
    101 v(p.Data); // 访问后继结点
    102 }
    103 p = p.Lchild;
    104 }
    105 }
    106 }
    107 }

    2.前序线索化二叉树以及前序遍历线索二叉树

    1 class PreOrderThread
    2 {
    3 //静态变量 _pre保存当前结点的前驱
    4 static BiThrNode _pre;
    5
    6 /// <summary>
    7 /// 二叉树前序线索化
    8 /// </summary>
    9 /// <param name="node"></param>
    10 public static void PreThreading(BiThrNode node)
    11 {
    12 if (node!=null)
    13 {
    14 if (node.Lchild==null)
    15 {
    16 node.LTag = Tag.Thread;
    17 node.Lchild = _pre; //前继线索
    18 }
    19 if (_pre.Rchlid==null)
    20 {
    21 _pre.RTag = Tag.Thread;
    22 _pre.Rchlid = node; //后继线索
    23 }
    24 _pre = node;
    25 if (Tag.Link == node.LTag)
    26 PreThreading(node.Lchild);
    27 if (Tag.Link == node.RTag)
    28 PreThreading(node.Rchlid);
    29 }
    30 }
    31 /// <summary>
    32 /// 为线索二叉树增加一个头结点,作为最左边结点前驱和最右边结点后继
    33 /// </summary>
    34 /// <param name="node"></param>
    35 /// <returns></returns>
    36 public static BiThrNode PreOrderThreading(BiThrNode node)
    37 {
    38 BiThrNode head = new BiThrNode(0);
    39 head.LTag = Tag.Link; // 建头结点
    40 head.RTag = Tag.Thread;
    41 head.Rchlid = head; // 右指针回指
    42 if (node == null)
    43 {
    44 head.Lchild = head;
    45 }
    46 else
    47 {
    48 head.Lchild = node;
    49 _pre = head;
    50 PreThreading(node); // 前序遍历进行前序线索化
    51
    52 _pre.Rchlid = head;
    53 _pre.RTag = Tag.Thread; // 最后一个结点线索化
    54 head.Rchlid = _pre;
    55 }
    56
    57 return head;
    58 }
    59 /// <summary>
    60 ///前序遍历线索二叉树
    61 /// </summary>
    62 /// <param name="node"></param>
    63 /// <param name="v"></param>
    64 public static void PreOrderTraverseThr(BiThrNode node, VisitClass.Visit v)
    65 {
    66 BiThrNode p;
    67 p = node.Lchild; // p指向根结点
    68 while (p != node)// 空树或遍历结束时,p==node
    69 {
    70 //通过左孩子先序遍历到最左端
    71 while (p.LTag == Tag.Link)
    72 {
    73 v(p.Data);
    74 p = p.Lchild;
    75
    76 }
    77 //无左孩子时,通过后继遍历
    78 while (p.RTag == Tag.Thread && p.Rchlid != node)
    79 {
    80 v(p.Data);
    81 p = p.Rchlid;
    82 }
    83 v(p.Data);
    84 if(p.LTag==Tag.Link)//下次循环遍历左子树
    85 {
    86 p = p.Lchild;
    87 }
    88 else //下次循环遍历右子树
    89 {
    90 p = p.Rchlid;
    91 }
    92 }
    93 }
    94
    95 }

    3.后序线索化二叉树以及后序遍历线索二叉树

    1 class PostOrderThread
    2 {
    3 //静态变量 _pre保存当中结点的中驱
    4 static BiThrNode _pre;
    5
    6 /// <summary>
    7 /// 二叉树后序线索化
    8 /// </summary>
    9 /// <param name="node"></param>
    10 public static void PostThreading(BiThrNode node)
    11 {
    12 if (node != null)
    13 {
    14 PostThreading(node.Lchild);
    15 PostThreading(node.Rchlid);
    16
    17 if (node.Lchild == null)
    18 {
    19 node.LTag = Tag.Thread;
    20 node.Lchild = _pre; //前驱线索
    21 }
    22 if (_pre.Rchlid == null)
    23 {
    24 _pre.RTag = Tag.Thread;
    25 _pre.Rchlid = node; //后继线索
    26 }
    27
    28 _pre = node;
    29 }
    30 }
    31 /// <summary>
    32 /// 获得当前结点的双亲
    33 /// </summary>
    34 /// <param name="node"></param>
    35 /// <returns></returns>
    36 public static BiThrNode GetParent(BiThrNode head, BiThrNode node)
    37 {
    38 BiThrNode temp = head;
    39 if (temp.Lchild == node)//父结点是头结点
    40 return head;
    41
    42 temp = temp.Lchild;
    43 while (temp.Lchild != node && temp.Rchlid != node)
    44 {
    45 if (Tag.Link == temp.RTag)
    46 temp = temp.Rchlid; //如果节点有右节点,则往右
    47 else
    48 temp = temp.Lchild; //如果节点没有右孩子,则去左孩子或前驱
    49 }
    50 return temp;
    51
    52 }
    53 public static BiThrNode PostOrderThreading(BiThrNode node)
    54 {
    55 BiThrNode head = new BiThrNode(0);
    56 head.LTag = Tag.Link; // 建头结点
    57 head.RTag = Tag.Thread;
    58 head.Rchlid = head; // 右指针回指
    59 if (node == null)
    60 {
    61 head.Lchild = head;
    62 }
    63 else
    64 {
    65 head.Lchild = node;
    66 _pre = head;
    67 PostThreading(node); // 后序遍历进行后序线索化
    68
    69 head.Rchlid = _pre;
    70 }
    71
    72 return head;
    73 }
    74 /// <summary>
    75 ///后序遍历线索二叉树
    76 /// </summary>
    77 /// <param name="node"></param>
    78 /// <param name="v"></param>
    79 public static void PostOrderTraverseThr(BiThrNode head, VisitClass.Visit v)
    80 {
    81 BiThrNode p = head.Lchild;
    82 BiThrNode par;
    83
    84 for (; ; )
    85 {
    86 while (Tag.Link == p.LTag)
    87 p = p.Lchild;
    88 if (Tag.Link == p.RTag)
    89 p = p.Rchlid;
    90 else
    91 break; //找到后序遍历中第一个被访问的节点
    92 }
    93 while (p != head)
    94 {
    95 v(p.Data);
    96 par = GetParent(head, p); //par是p的双亲:
    97
    98 if (head == par) //1.若parent是head,即p是根节点,则无后继
    99 p = head;
    100 else if (p == par.Rchlid || Tag.Thread == par.RTag) //2.若p是双亲的右孩子,或者是独生左孩子,则后继为双亲
    101 p = par;
    102 else
    103 {
    104 while (par.RTag == Tag.Link) //3.若p是有兄弟的左孩子,则后继为双亲的右子树上按照后续遍历访问的第一个节点。
    105 {
    106 par = par.Rchlid;
    107 while (par.LTag == Tag.Link)
    108 {
    109 par = par.Lchild;
    110 }
    111 }
    112 p = par;
    113 }
    114 }
    115 }//后序遍历
    116
    117 }

  • 相关阅读:
    iOS:CoreData数据库的使用二(创建多个数据库表,表之间有对应关系)
    iOS:CoreData数据库的使用一(创建单个数据库表)
    iOS:第三方数据库文件FMDB的使用
    H.264 Profile、Level、Encoder三张简图 (fps = AVCodecContext->time_base.den / AVCodecContext->time_base.num)
    proftpd的示例配置文件
    linux定时器HZ和Jiffies
    labview
    linux c 及 c++打印调用者函数caller function的方法,包括arm c平台
    vim 设置 swap file, 防止 同一个文件同时被多次打开,而且有恢复的功效
    Make 命令教程
  • 原文地址:https://www.cnblogs.com/zhaos/p/1945906.html
Copyright © 2011-2022 走看看