1  /  1  页   1 跳转 查看:202

线索二叉树

线索二叉树

线索二叉树主要是为了解决查找结点的线性前驱与后继不方便的难题。它只增加了两个标志性域,就可以充分利用没有左或右孩子的结点的左右孩子的存储空间来存放该结点的线性前驱结点与线性后继结点。两个标志性域所占用的空间是极少的,所有充分利用了二叉链表中空闲存的储空间。
要实现线索二叉树,就必须定义二叉链表结点数据结构如下(定义请看代码):
Lnode
Ltag
Data
Rtag
Rnode




说明:
1.
Ltag=0时,表示Lnode指向该结点的左孩子;
2.
Ltag=1时,表示Lnode指向该结点的线性前驱结点;
3.
Rtag=0时,表示Rnode指向该结点的右孩子;
4.
Rnode时,表示Rnode指向该结点的线性后继结点;
    以二叉链表结点数据结构所构成的二叉链表作为二叉树的存储结构,叫做线索二叉链表;指向结点的线性前驱或者线性后继结点的指针叫做线索;加上线索的二叉树称为线索二叉树;对二叉树以某种次序遍历将其变为线索二叉树的过程叫做线索化。

中序次序线索化二叉树算法:

中序次序线索化是指用二叉链表结点数据结构建立二叉树的二叉链表,然后按照中序遍历的方法访问结点时建立线索;(具体看代码)
检索中序二叉树某结点的线性前驱结点的算法:
1.
如果该结点的Ltag=1,那么Lnode就是它的线性前驱;
2.
如果该结点的Ltag=0,那么该结点左子树最右边的尾结点就是它的线性前驱点;
(具体请看代码)
检索中序二叉树某结点的线性后继结点和算法:
1.
如果该结点的Rtag=1,那么Rnode就是它的线性后继结点;
2.
如果该结眯的Rtag=0,那么该结点右子树最左边的尾结点就是它的线性后继结点
(具体请看代码)

  解决方案中所有到二叉树的中序线索二叉树和中序线索链表的图




解决方案源码

二叉树中序线索算法解决方案
using System;
using System.Collections.Generic;
using System.Text;
/**//*
作者:旋风
日期:2006-9-29
博客园主页:
http://xuanfeng.cnblogs.com
内容:线索二叉树

*/
namespace LineNode
{
   

   
class Program
   
{
       
二叉链表结点数据结构的定义#region 二叉链表结点数据结构的定义
       
class LineNodes<T>
       
{
            T data;
            LineNodes
<T> lNode, rNode;
           
int lTag, rTag;
           
public LineNodes(T data)
           
{
               
this.data = data;

            }


           
public T Data
           
{
               
set
               
{

                    data
= value;
                }

               
get
               
{

                   
return data;

                }


            }


           
public LineNodes<T> Lnode
           
{
               
set
               
{
                    lNode
= value;
                }

               
get
               
{
                   
return lNode;
                }

            }


           
public LineNodes<T> Rnode
           
{
               
set
               
{
                    rNode
= value;
                }

               
get
               
{

                   
return rNode;
                }


            }


           
public
int Ltag
           
{
               
set
               
{
                    lTag
= value;

                }


               
get
               
{
                   
return rTag;

                }


            }


           
public
int Rtag
           
{
               
set
               
{
                    rTag
= value;
                }

               
get
               
{
                   
return rTag;

                }


            }

        }

       
#endregion

       
构造一颗已知的线索二叉树#region 构造一颗已知的线索二叉树
       
static LineNodes<string> GetLineTree()
       
{
            LineNodes
<string>[] lineNodes =
new LineNodes<string>[9];
            lineNodes[
0] =
new LineNodes<string>("A");
            lineNodes[
1] =
new LineNodes<string>("B");
            lineNodes[
2] =
new LineNodes<string>("C");
            lineNodes[
3] =
new LineNodes<string>("D");
            lineNodes[
4] =
new LineNodes<string>("E");
            lineNodes[
5] =
new LineNodes<string>("F");
            lineNodes[
6] =
new LineNodes<string>("G");
            lineNodes[
7] =
new LineNodes<string>("H");
            lineNodes[
8] =
new LineNodes<string>("I");

            lineNodes[
0].Lnode = lineNodes[1];
            lineNodes[
0].Rnode = lineNodes[2];

            lineNodes[
1].Lnode = lineNodes[3];
            lineNodes[
1].Rnode = lineNodes[4];

            lineNodes[
2].Lnode = lineNodes[5];
            lineNodes[
2].Rnode = lineNodes[6];

            lineNodes[
4].Lnode = lineNodes[7];
            lineNodes[
4].Rnode = lineNodes[8];


           
return lineNodes[0];


        }

       
#endregion

       
中序次序线索化算法#region 中序次序线索化算法
       
static LineNodes<string> preNode =
null;//定义一个全局变量保存当前结点的前驱

static
void MidOrder(LineNodes<string> headNode, LineNodes<string> postNode)
       
{
           
if (headNode !=
null)
           
{
                MidOrder(headNode.Lnode, headNode);

                Console.WriteLine(headNode.Data);

               
if (headNode.Lnode !=
null)
               
{
                    headNode.Ltag
=
0;

                }

               
else
               
{
                    headNode.Ltag
=
1;
                    headNode.Lnode
= preNode;

                }



                preNode
= headNode;
                MidOrder(headNode.Rnode, postNode);

               
if (headNode.Rnode !=
null)
               
{

                    headNode.Rtag
=
0;
                }


               
else
               
{

                    headNode.Rtag
=
1;
                    headNode.Rnode
= postNode;
                }




            }


        }

       
#endregion


       
在中根线索树上查找结点node的前驱结点#region 在中根线索树上查找结点node的前驱结点
       
static LineNodes<string> GetPreNode(LineNodes<string> node)
       
{
            LineNodes
<string> preNode =
null;
           
if (node !=
null)
           
{
               
if (node.Ltag ==
1)
               
{
                    preNode
= node.Lnode;
                }

               
else
               
{
                   
while (node.Rtag !=
1)
                   
{
                        node
= node.Rnode;

                    }

                    preNode
= node;
                }

               
return preNode;
            }

           
return
null;
        }

       
#endregion

       
在中根线索树上查找结点node的后继结点#region 在中根线索树上查找结点node的后继结点
       
static LineNodes<string> GetPostNode(LineNodes<string> node)
       
{
            LineNodes
<string> postNode;
           
if (node !=
null)
           
{
               
if (node.Rtag ==
1)
               
{
                    postNode
= node.Rnode;
                }

               
else
               
{
                   
while (node.Lnode.Ltag !=
1)
                   
{
                        node
= node.Lnode;

                    }

                    postNode
= node;

                }

               
return postNode;
            }

           
return
null;
           
        }

       
#endregion


       
测试的主办法#region 测试的主办法
       
static
void Main(string[] args)
       
//得到已知二叉树的根结点
            LineNodes<string> headNode = GetLineTree();
           
//中序线索化已知二叉树
            MidOrder(headNode, headNode);
           
//测试,查找结点I的前驱
            Console.WriteLine("结点I的线性前驱结点是:");//正确应该是:E
            Console.WriteLine(GetPreNode(headNode.Lnode.Rnode.Rnode).Data);
            Console.WriteLine(
"结点F的线性后继结点是:");//正确应该是C
            Console.WriteLine(GetPostNode(headNode.Rnode.Lnode).Data);
            Console.Read();
        }

       
#endregion
    }

}


作者:旋风
 

回复:线索二叉树

不错,很有收获~~~~
 
1  /  1  页   1 跳转

版权所有 GIS动力  GIS动力资源仓库 FreeMap 免责声明  Sitemap

Powered by Discuz!NT 2.0.1214    Copyright © 2001-2008 Comsenz Inc.
Processed in 0.875 second(s) , 15 queries. 滇ICP备05006901号
返顶部