面试题1:二叉树变双向链表

 

输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。

要求不能创建任何新的结点,只调整指针的指向。

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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值