目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何
新的结点,只调整指针的指向。
比如将二元查找树
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16
#include <iostream>
using namespace std;
struct Node{
int value;
Node* left;
Node* right;
};
//主程序
void Convert(Node* proot,Node* &pLast){
if(proot==NULL){
return;
}
Node* pNode=proot;
if(pNode->left!=NULL){
Convert(pNode->left,pLast);
}
pNode->left=pLast;
if(pLast!=NULL){
pLast->right=pNode;
}
pLast=pNode;
if(pNode->right!=NULL){
Convert(pNode->right,pLast);
}
}
//驱动程序
Node* ConvertToList(Node* proot){
if(proot==NULL){
return proot;
}
Node* pLastInList=NULL;
Convert(proot,pLastInList);
//返回头结点
Node* pHead=pLastInList;
while(pHead!=NULL && pHead->left!=NULL){
pHead=pHead->left;
}
return pHead;
}
Node* create(int value,Node* left=NULL,Node* right=NULL){
Node* pnode=new Node;
pnode->value=value;
pnode->left=left;
pnode->right=right;
return pnode;
}
//preorder
void PrintTree(Node* root){
if(root==NULL){
return;
}
cout<<root->value<<ends;
PrintTree(root->left);
PrintTree(root->right);
}
void PrintList(Node* head){
Node* p=head;
while(p!=NULL){
cout<<p->value<<ends;
p=p->right;
}
}
int main()
{
Node* d=create(4);
Node* e=create(8);
Node* f=create(12);
Node* g=create(16);
Node* b=create(6,d,e);
Node* c=create(14,f,g);
Node* a=create(10,b,c);
PrintTree(a);
cout<<endl;
Node* head=ConvertToList(a);
PrintList(head);
cout<<endl;
return 0;
}
思路二:我们可以中序遍历整棵树。按照这个方式遍历树,比较小的结点先访问。如果我们每访问一个结点,假设之前访问过的结点已经调整成一个排序双向链表,我们再把调整当前结点的指针将其链接到链表的末尾。当所有结点都访问过之后,整棵树也就转换成一个排序双向链表了