您的位置:首页 > 其它

(三)二元查找树转换双向链表

2011-04-16 15:37 239 查看
题意:不引入新节点,只允许指针操作,实现二元查找树转换为相应双向链表。

    10

   /    /

  6    14

 / /    /  /

4  8 12 16

转换成双向链表

4=6=8=10=12=14=16

 

 

分析:

方法0:转换后的双向链表正好为原树的中序遍历,所以引入一个新指针递归遍历即可。

方法1:从10节点看,它的前趋、后继分别是左子树的最右节点与右子树的最左节点,所以找到前趋与后继保存,递归实现即可。

 

 

代码中验证Btree建立成功分别用先序、中序与后序来遍历。然后又用到了Btree拷贝方法验证两种tree2list方法。

C++实现:

#include <iostream>
#include <stack>
using namespace std;

struct btree{
btree(int v):val(v), l(NULL), r(NULL){}
int val;
btree *l, *r;
};

void preorder(btree* head){
btree* tmp = head;
stack<btree*> s;
while(!s.empty() || tmp!=NULL){
while(tmp!=NULL){
s.push(tmp);
cout << s.top()->val << "/t";
tmp=tmp->l;
}
tmp=s.top()->r;
s.pop();
}
}
void inorder(btree* head){
btree* tmp = head;
stack<btree*> s;
while(!s.empty() || tmp!=NULL){
while(tmp!=NULL){
s.push(tmp);
tmp=tmp->l;
}
tmp=s.top()->r;
cout << s.top()->val << "/t";
s.pop();
}
}

void postorder(btree* head){
btree* tmp = head;
stack<btree*> s;
stack<bool> f;
while(!s.empty() || tmp!=NULL){
while(tmp!=NULL){
s.push(tmp);
f.push(false);
tmp=tmp->l;
}
if(f.top()==false){
tmp=s.top()->r;
f.pop();
f.push(true);
}else{
cout << s.top()->val << "/t";
s.pop();
f.pop();
}
}
}

void walklist(btree* head){
btree* tmp=head;
while(tmp!=NULL){
cout << tmp->val << "/t";
tmp=tmp->r;
}
}

//way0: inorder travel
void tree2list(btree* bt,btree*& list)
{
if(bt->l!=NULL)
tree2list(bt->l, list);
if(list!=NULL){
list->r = bt;
bt->l = list;
list = bt;
}else{
list=bt;
}
if(bt->r)
tree2list(bt->r, list);
}

//way1: find the pre and post
btree* getRight(btree* bt){
if(bt==NULL) return bt;
while(bt->r!=NULL){
bt = bt->r;
}
return bt;
}
btree* getLeft(btree* bt){
if(bt==NULL) return bt;
while(bt->l!=NULL){
bt = bt->l;
}
return bt;
}
void tree2list1(btree*& bt){
btree *pre, *post;

if(bt==NULL) return;
pre = getRight(bt->l);
post = getLeft(bt->r);
if(bt->l!=NULL) tree2list1(bt->l);
if(bt->r!=NULL) tree2list1(bt->r);
bt->l = pre;
if(pre!=NULL) pre->r = bt;
bt->r = post;
if(post!=NULL) post->l = bt;
}

btree* treeCopy(btree* bt){
if(bt==NULL) return bt;
btree* tmp = new btree(bt->val);
if(bt->l!=NULL) tmp->l = treeCopy(bt->l);
if(bt->r!=NULL) tmp->r = treeCopy(bt->r);
return tmp;
}

int main()
{
/*creat tree*/
btree *n1 = new btree(10);
btree *n2 = new btree(6);
btree *n3 = new btree(14);
btree *n4 = new btree(4);
btree *n5 = new btree(8);
btree *n6 = new btree(12);
btree *n7 = new btree(16);

//creat Btree
n1->l = n2, n1->r = n3;
n2->l = n4, n2->r = n5;
n3->l = n6, n3->r = n7;
btree *n8 = treeCopy(n1);

//travel Btree
cout << "Preorder:/t";
preorder(n1);
cout << endl;
cout << "Midorder:/t";
inorder(n1);
cout << endl;
cout << "Postorder:/t";
postorder(n1);
cout << endl;

//Way0: Btree to list
btree* list=NULL;
tree2list(n1,list);
list = n1;
while(list!=NULL && list->l!=NULL)
list=list->l;
cout << "DoubleList:/t";
walklist(list);
cout << endl;

//Way1: Btree to list
tree2list1(n8);
list = n8;
while(list!=NULL && list->l!=NULL)
list=list->l;
cout << "DoubleList1:/t";
walklist(list);
cout << endl;

return 0;
}
  

 

 

运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  list null bt tree n2 c