线索二叉树

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 }

posted @ 2011-01-27 03:54  zhaos  阅读(1751)  评论(2编辑  收藏  举报