线索二叉树

  在二叉树2n个链中,总共有n+1是空链。A.J.Perlis 和 C.Thornton一想出种巧妙的方法来利用利用这些空链。即线索二叉树

线索建立规则:

1.如果ptr的左子树ptr->left_child==null,则在中序遍历中,ptr->left_child指向ptr的序列的前驱结点,来替代空链

2.如果ptr的左子树ptr->right_child==null,则在中序遍历中,ptr->right_child指向ptr的序列的后继结点,来替代空链

线索结构说明

template <class T> struct thread_tree_node
{
	T data;
	thread_tree_node<T> *lchild,*rchild;
	bool left_thread,right_thread;
};

其中 left_thread=true 表示lchild指向的是线索否则是左子树,同样right_threads

例如图(a)是一棵中序线索二叉树,它的线索链表如图(b)所示s

 

线索二叉树

图a

线索二叉树

图b

 

线索二叉树实现
  1 //线索树
2 template <class T> class thread_tree
3 {
4 public:
5 thread_tree();
6 ~thread_tree();
7 void convert2thread(tree<T> &);
8 void travel();
9 thread_tree_node<T> *root;
10
11
12 private:
13 thread_tree_node<T> *find_next(thread_tree_node<T> * node);
14 thread_tree_node<T> head;
15 thread_tree_node<T> * copy_base( tree_node<T> *p);
16
17 };
18
19 //构造函数
20 template<class T> thread_tree<T>::thread_tree()
21 {
22 head.data=0;
23 head.left_thread=head.right_thread=false;
24 head.lchild=NULL;
25 head.rchild=&head;
26 root=&head;
27 }
28
29 //析构函数
30 template <class T> thread_tree<T> ::~thread_tree()
31 {
32 thread_tree_node<T> *p=find_next(root);
33 thread_tree_node<T> *temp=NULL;
34 while (p!=root)
35 {
36 temp=p;
37 p=find_next(p);
38 delete temp;
39 }
40
41 cout<<"destruct over"<<endl;
42
43 }
44
45 //将一棵树转化为线索树
46 template <class T> void thread_tree<T>::convert2thread(tree<T> &obj)
47 {
48 stack_list<thread_tree_node<T>* > stack;
49
50 tree_node<T> *tree_root=obj.get_root();
51
52
53 //空树
54 if(!tree_root)
55 return;
56 // 够着基本树结构
57
58 head.lchild=copy_base(tree_root);
59
60 thread_tree_node<T> *p=head.lchild;
61 thread_tree_node<T> * previous=NULL;
62
63 //对root中序遍历,并建立线索树节点
64 while (1)
65 {
66 //左节点进栈
67 while (p)
68 {
69 stack.push(p);
70 p=p->lchild;
71 }
72
73 //栈空结束
74 if(stack.isEmpty())
75 break;
76
77 //出栈,并设置线索
78 p=stack.Top();
79 //cout<<p->data<<" left:"<<p->left_thread<<" right:"<<p->right_thread<<endl;
80 stack.pop();
81
82 //前驱线索
83 if(p->left_thread)
84 {
85 if (previous==NULL)
86 p->lchild=root;
87 else
88 p->lchild=previous;
89 }
90
91 //后继线索
92 if(p->right_thread)
93 {
94 if (stack.isEmpty())
95 p->rchild=root;
96 else
97 p->rchild=stack.Top();
98 }
99
100 previous=p;
101
102 if (p->right_thread)
103 p=NULL;
104 else
105 p=p->rchild;
106
107 }
108 cout<<"convert to thread tree successful"<<endl;
109 }
110
111 //复制基本的树结构
112 template <class T> thread_tree_node<T> * thread_tree<T>::copy_base(tree_node<T> *p)
113 {
114 if (p)
115 {
116 thread_tree_node<T> *thread_p =new thread_tree_node<T>;
117 if (!thread_p)
118 {
119 cout<<"new thread tree node error"<<endl;
120 }
121 else
122 {
123 thread_p->data=p->value;
124 if (p->lchild)
125 thread_p->left_thread=false;
126 else
127 thread_p->left_thread=true;
128
129 if (p->rchild)
130 thread_p->right_thread=false;
131 else
132 thread_p->right_thread=true;
133
134 thread_p->lchild=copy_base(p->lchild);
135 thread_p->rchild=copy_base(p->rchild);
136 }
137 return thread_p;
138 }
139 else
140 {
141 return NULL;
142 }
143 }
144
145
146 //线索遍历,中序
147 template<typename T> void thread_tree<T>::travel()
148 {
149 thread_tree_node<T> *temp=root;
150 while(1)
151 {
152 temp=find_next(temp);
153 if (temp==root)
154 break;
155 cout<<temp->data;
156 }
157
158 cout<<"\ninorder travel over"<<endl;
159
160 }
161
162 //寻找后继节点
163 template<class T> thread_tree_node<T>* thread_tree<T>::find_next(thread_tree_node<T> * node)
164 {
165 //线索
166 if (node->right_thread)
167 {
168 return node->rchild;
169 }
170 else
171 {
172 thread_tree_node<T> *temp=node->rchild;
173 while (!temp->left_thread)
174 {
175 temp=temp->lchild;
176 }
177 return temp;
178 }
179
180 }


 

posted on 2011-09-06 19:31  youngkang  阅读(380)  评论(0)    收藏  举报