线索二叉树

线索二叉树主要是为了解决查找结点的线性前驱与后继不方便的难题。它只增加了两个标志性域,就可以充分利用没有左或右孩子的结点的左右孩子的存储空间来存放该结点的线性前驱结点与线性后继结点。两个标志性域所占用的空间是极少的,所有充分利用了二叉链表中空闲存的储空间。

   要实现线索二叉树,就必须定义二叉链表结点数据结构如下(定义请看代码):

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,那么该结点右子树最左边的尾结点就是它的线性后继结点

(具体请看代码)

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




解决方案源码

ContractedBlock.gif ExpandedBlockStart.gif 二叉树中序线索算法解决方案
None.gifusing System;
None.gif
using System.Collections.Generic;
None.gif
using System.Text;

None.gif
namespace LineNode
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
InBlock.gif
InBlock.gif    
class Program
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ContractedSubBlock.gifExpandedSubBlockStart.gif        
二叉链表结点数据结构的定义#region 二叉链表结点数据结构的定义
InBlock.gif        
class LineNodes<T>
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            T data;
InBlock.gif            LineNodes
<T> lNode, rNode;
InBlock.gif            
int lTag, rTag;
InBlock.gif            
public LineNodes(T data)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this.data = data;
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
public T Data
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
set
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    data 
= value;
ExpandedSubBlockEnd.gif                }

InBlock.gif                
get
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    
return data;
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
public LineNodes<T> Lnode
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
set
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    lNode 
= value;
ExpandedSubBlockEnd.gif                }

InBlock.gif                
get
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
return lNode;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
public LineNodes<T> Rnode
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
set
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    rNode 
= value;
ExpandedSubBlockEnd.gif                }

InBlock.gif                
get
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    
return rNode;
ExpandedSubBlockEnd.gif                }

InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
public int Ltag
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
set
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    lTag 
= value;
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
get
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
return rTag;
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
public int Rtag
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
set
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    rTag 
= value;
ExpandedSubBlockEnd.gif                }

InBlock.gif                
get
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
return rTag;
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }
 
ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
构造一颗已知的线索二叉树#region 构造一颗已知的线索二叉树
InBlock.gif        
static LineNodes<string> GetLineTree()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            LineNodes
<string>[] lineNodes = new LineNodes<string>[9];
InBlock.gif            lineNodes[
0= new LineNodes<string>("A");
InBlock.gif            lineNodes[
1= new LineNodes<string>("B");
InBlock.gif            lineNodes[
2= new LineNodes<string>("C");
InBlock.gif            lineNodes[
3= new LineNodes<string>("D");
InBlock.gif            lineNodes[
4= new LineNodes<string>("E");
InBlock.gif            lineNodes[
5= new LineNodes<string>("F");
InBlock.gif            lineNodes[
6= new LineNodes<string>("G");
InBlock.gif            lineNodes[
7= new LineNodes<string>("H");
InBlock.gif            lineNodes[
8= new LineNodes<string>("I");
InBlock.gif
InBlock.gif            lineNodes[
0].Lnode = lineNodes[1];
InBlock.gif            lineNodes[
0].Rnode = lineNodes[2];
InBlock.gif
InBlock.gif            lineNodes[
1].Lnode = lineNodes[3];
InBlock.gif            lineNodes[
1].Rnode = lineNodes[4];
InBlock.gif
InBlock.gif            lineNodes[
2].Lnode = lineNodes[5];
InBlock.gif            lineNodes[
2].Rnode = lineNodes[6];
InBlock.gif
InBlock.gif            lineNodes[
4].Lnode = lineNodes[7];
InBlock.gif            lineNodes[
4].Rnode = lineNodes[8];
InBlock.gif
InBlock.gif
InBlock.gif            
return lineNodes[0];
InBlock.gif
InBlock.gif
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif        
#endregion

InBlock.gif
ContractedSubBlock.gifExpandedSubBlockStart.gif        
中序次序线索化算法#region 中序次序线索化算法
InBlock.gif        
static LineNodes<string> preNode = null;//定义一个全局变量保存当前结点的前驱
InBlock.gif
        static void MidOrder(LineNodes<string> headNode, LineNodes<string> postNode)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (headNode != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                MidOrder(headNode.Lnode, headNode);
InBlock.gif
InBlock.gif                Console.WriteLine(headNode.Data);
InBlock.gif
InBlock.gif                
if (headNode.Lnode != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    headNode.Ltag 
= 0;
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    headNode.Ltag 
= 1;
InBlock.gif                    headNode.Lnode 
= preNode;
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif
InBlock.gif                preNode 
= headNode;
InBlock.gif                MidOrder(headNode.Rnode, postNode);
InBlock.gif
InBlock.gif                
if (headNode.Rnode != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    headNode.Rtag 
= 0;
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    headNode.Rtag 
= 1;
InBlock.gif                    headNode.Rnode 
= postNode;
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif
InBlock.gif
ExpandedSubBlockEnd.gif            }

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

InBlock.gif                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
while (node.Rtag != 1)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        node 
= node.Rnode;
InBlock.gif
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    preNode 
= node;
ExpandedSubBlockEnd.gif                }

InBlock.gif                
return preNode;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return null;
ExpandedSubBlockEnd.gif        }
 
ExpandedSubBlockEnd.gif        
#endregion

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

InBlock.gif                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
while (node.Lnode.Ltag != 1)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        node 
= node.Lnode;
InBlock.gif
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    postNode 
= node;
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif                
return postNode;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
return null;
InBlock.gif            
ExpandedSubBlockEnd.gif        }
 
ExpandedSubBlockEnd.gif        
#endregion

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

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

转载于:https://www.cnblogs.com/yuchen198112/archive/2007/01/02/610058.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值