输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ /
6 14
/ / / /
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
算法思想:
1,递归;以某个节点为根的子树所生成的链表=(左子树生成的链表)+根节点+(右子树生成的链表)
2,循环;按照中序遍历的非递归方法,把节点压栈;弹栈弹出的节点依次挂到链表上
代码:
#include <iostream>
#include <stack>
using namespace std;
class Node{//Node节点的结构
public:
int key;
Node * left;
Node * right;
Node(int k):key(k),left(NULL),right(NULL){}
Node(void):key(0),left(NULL),right(NULL){}
};
class BTree{//Tree的结构
public:
Node * root;
BTree():root(NULL){}
};
class RList{//双向链表的结构
public:
Node * head;
Node * rear;
RList():head(NULL),rear(NULL){}
};
void AddNode(Node * new_node,Node * & root){//向二叉查找树中加入节点。此处第二个参数必须是Node * &。
if(root==NULL)
root=new_node;
else{
if(root->key>new_node->key)
AddNode(new_node,root->left);
else if(root->key<new_node->key)
AddNode(new_node,root->right);
}
}
RList * BTreeToList(Node * root){//递归的方法求双向链表
if(root==NULL){
RList * list=new RList();
return list;
}
else{
RList * left_list=BTreeToList(root->left);
RList * right_list=BTreeToList(root->right);
RList * list=new RList();
if(left_list->head==NULL){//如果左边的表是空表
list->head=root;
}
else{
list->head=left_list->head;
left_list->rear->right=root;//把root节点挂到左边的链表的尾部
root->left=left_list->rear;
}
if(right_list->rear==NULL){//右边的表是空表
list->rear=root;
}
else{
list->rear=right_list->rear;
root->right=right_list->head;//把root节点挂到右边的链表的头部
right_list->head->left=root;
}
return list;
}
}
RList * BTreeToListWithStack(BTree * bt){//非递归的方法建立双链表;使用循环法中序遍历的思想
stack<Node *> nodestack;//栈——保存节点
nodestack.push(bt->root);
RList * RL=new RList();
while (!nodestack.empty()){
Node * node=nodestack.top()->left;
nodestack.top()->left=NULL;//如果没有这一步会出现什么??
if(node!=NULL){
nodestack.push(node);
}
else{
Node * popednode=nodestack.top();
nodestack.pop();//弹栈
if (popednode->right!=NULL) {
nodestack.push(popednode->right);
}
//将popednode挂到链表上
if(RL->head==NULL){
RL->head=popednode;
RL->rear=popednode;
}
else{
RL->rear->right=popednode;
popednode->left=RL->rear;
RL->rear=popednode;
}
//挂接完成
}
}
return RL;
}
int main(){
BTree * bt=new BTree();
for(int i=0;i<5;i++){
int a=0;
cin>>a;
Node * new_Node=new Node(a);
AddNode(new_Node,bt->root);
}
RList * RL=BTreeToListWithStack(bt);
//输出双向链表
Node * index=RL->head;
do{
cout<<index->key<<' ';
index=index->right;
} while (index!=RL->rear);
cout<<RL->rear->key<<endl;
return 0;
}