《剑指Offer》面试题:二叉搜索树转换为双向链表

来源:互联网 发布:php httpclient cookie 编辑:程序博客网 时间:2024/05/17 22:29

题目描述:
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

思路
这道题目关键在于不能创建新的节点,如不然,我们可以直接将二叉排序树中序遍历保存到一个数组中,而后再建立一个双性链表,将数据保存到双向链表里。
此题就是中序遍历的一个变种;利用中序遍历递归即可完成,每次递归都保存一个指向已构造好的双向链表的尾节点的指针,将其与下一个节点连接起来。

/*输入:输入可能包含多个测试样例。对于每个测试案例,输入的第一行为一个数n(0<n<1000),代表测试样例的个数。接下来的n行,每行为一个二叉搜索树的先序遍历序列,其中左右子树若为空则用0代替。输出:对应每个测试案例,输出将二叉搜索树转换成排序的双向链表后,从链表头至链表尾的遍历结果。样例输入:12 1 0 0 3 0 0样例输出:1 2 3*//*思路:按照中序遍历来进行转换 */#include<stdio.h>#include<stdlib.h>struct Node{    int mValue;    struct Node *pLeft;    struct Node *pRight;};//创建二叉搜索树void createBSTree(Node **ppNode){    int val;    scanf("%d",&val);    if(val==0){        *ppNode=NULL;    }    else{        *ppNode=(Node *)malloc(sizeof(Node));        if(*ppNode==NULL){            exit(EXIT_FAILURE);        }        (*ppNode)->mValue=val;        (*ppNode)->pLeft=NULL;        (*ppNode)->pRight=NULL;        createBSTree(&((*ppNode)->pLeft));        createBSTree(&((*ppNode)->pRight));    }}//按中序遍历来进行节点的指针的改变, void covertNode(Node *pRoot,Node **pLast){    if(pRoot==NULL)        return;    //先转换左子树    if(pRoot->pLeft!=NULL){        covertNode(pRoot->pLeft,pLast);    }     //将二叉搜索树的头节点连接到链表的后边    pRoot->pLeft=*pLast;//将当前结点(即即将要加入链表的新节点)的左指针指向链表的尾部     if(*pLast!=NULL){        (*pLast)->pRight=pRoot;//将当前链表中的右指针指向新节点。     }     *pLast=pRoot;//移动链表的指针至新节点的位置     //再转换右子树    if(pRoot->pRight!=NULL){        covertNode(pRoot->pRight,pLast);    } }//返回双向链表的头结点,形参为树的根结点Node * covertTree2List(Node *pRoot){    if(pRoot==NULL)        return NULL;    if(pRoot->pLeft==NULL&&pRoot->pRight==NULL){//只有一个节点的树         return pRoot;    }    Node *pLast=NULL;//用来指向链表的尾结点     covertNode(pRoot,&pLast);    //返回头结点    Node *pHead=pLast;    while(pHead->pLeft!=NULL){        pHead=pHead->pLeft;    }    return pHead;}int main(void){    int n;    while(scanf("%d",&n)!=EOF){        if(n>0){            for(int i=0;i<n;i++){                Node *pRoot;                //第一步:创建BSTree。                 createBSTree(&pRoot);//参数为节点指针的指针                //第二步:开始转换                Node *pHead=covertTree2List(pRoot);                 //第三步:输出                while(pHead!=NULL){                    printf("%d  ",pHead->mValue);                    pHead=pHead->pRight;                }                printf("\n");                free(pRoot);                pRoot=NULL;             }        }    }       return 0;} 
0 0