微软等数据结构与算法面试100题 第一题

第一题
题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的节点,只能调整指针的指向。 参考了July的整理。表示感谢。

  10
      / /
  6  14
/ / / /
4  8 12 16
  
转换成双向链表
4=6=8=10=12=14=16。

分析:
由上面的例子可以看到,在对于树进行遍历的时候使用了中序遍历方法,依次修改树中节点的前指向和后指向。
因为是要求不能创建新的节点,因为在中序遍历修改指向的时候,需要一个指针指向上次遍历的那个节点的地址,以便于
当前指针的指向,因此需要一个指针。(这个应该不算是节点的创建吧?)

因此,程序主要分为两个部分,一个是树的构建(节点的插入函数),另一个是在树的中序遍历,并且在中序遍历的过程中,修改
当前遍历的节点的前指向和后指向。

代码如下:

#include<iostream> 
#include<stdio.h> 
  
 
using namespace std; 
 
typedef struct BSTreeNode 
{ 
    float value; 
    BSTreeNode * NodeLeft; 
    BSTreeNode * NodeRight; 
}DoubleList; 
 
DoubleList * listHead; 
DoubleList * listIndex; 
 
void convert2DoubleLIST(BSTreeNode * nodeCurrent); 
void InOrder(BSTreeNode * root) 
{ 
    if(NULL==root) 
    { 
        return; 
    } 
    if(root->NodeLeft!=NULL) 
    { 
        InOrder(root->NodeLeft); 
    } 
 
    convert2DoubleLIST(root); 
 
    if(NULL!=root->NodeRight) 
    { 
        InOrder(root->NodeRight); 
    } 
} 
 
void convert2DoubleLIST(BSTreeNode * nodeCurrent) 
{ 
    //listIndex存储上次的记录 
    nodeCurrent->NodeLeft = listIndex; 
     
    if(NULL==listIndex) 
    { 
        listHead = nodeCurrent; 
    } 
    else 
    //这里面都是对地址进行操作 
    { 
        //上次处理的节点 
        listIndex->NodeRight = nodeCurrent; 
    } 
 
    listIndex = nodeCurrent; 
    cout<<nodeCurrent->value<<endl; 
 
} 
 
void addBSTreeNode(BSTreeNode * & root, float value){ 
 
    //创建二叉搜索树 
    if(NULL==root)//这样写是因为root==NULL容易写成root=NULL 
    { 
        BSTreeNode *paddNode = new BSTreeNode(); 
        paddNode->value = value; 
        paddNode->NodeLeft = NULL; 
        paddNode->NodeRight = NULL; 
        root = paddNode; 
    } 
    else 
    { 
        if(value < root->value) 
        { 
            addBSTreeNode(root->NodeLeft,value);  
        } 
        else if(value > root->value) 
        { 
            addBSTreeNode(root->NodeRight,value);     
        } 
        else 
        { 
            cout<<"重复插入节点"<<endl; 
        } 
    } 
 
} 
 
int main(){ 
 
    listIndex = NULL; 
    BSTreeNode * root = NULL; 
    addBSTreeNode(root,10); 
    addBSTreeNode(root,6); 
    addBSTreeNode(root,4); 
    addBSTreeNode(root,8); 
    addBSTreeNode(root,12); 
    addBSTreeNode(root,14); 
    addBSTreeNode(root,16); 
    addBSTreeNode(root,15); 
 
    InOrder(root); 
 
    return 0; 
} 

struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};
ANSWER:
This is a traditional problem that can be solved using recursion.
For each node, connect the double linked lists created from left and right child node to form a full list.
/**
* @param root The root node of the tree
* @return The head node of the converted list.
*/
BSTreeNode * treeToLinkedList(BSTreeNode * root) {
BSTreeNode * head, * tail;
helper(head, tail, root);
return head;
}
void helper(BSTreeNode *& head, BSTreeNode *& tail, BSTreeNode *root) {
BSTreeNode *lt, *rh;
if (root == NULL) {
head = NULL, tail = NULL;
return;
}
helper(head, lt, root->m_pLeft);
helper(rh, tail, root->m_pRight);
if (lt!=NULL) {
lt->m_pRight = root;
root->m_pLeft = lt;
} else {
head = root;
}
if (rh!=NULL) {
root->m_pRight=rh;
rh->m_pLeft = root;
} else {
tail = root;
}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值