【剑指Offer】题27:二叉搜索树与双向链表

本文介绍了一种将二叉搜索树转换为排序双向链表的方法,通过中序遍历的方式,调整树中结点指针的指向,实现转换而无需创建新节点。文章提供了完整的C语言实现代码。
题目描述:

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

输入:

输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为一个数n(0<n<1000),代表测试样例的个数。
接下来的n行,每行为一个二叉搜索树的先序遍历序列,其中左右子树若为空则用0代替。

输出:

对应每个测试案例,
输出将二叉搜索树转换成排序的双向链表后,从链表头至链表尾的遍历结果。

样例输入:

1
2 1 0 0 3 0 0
样例输出:

1 2 3
#include<stdio.h>
#include<stdlib.h>
  
typedef struct BSTNode
{
    int data;
    struct BSTNode *left;
    struct BSTNode *right;
}BSTNode,*BSTree;
  
/*
根据题目要求的格式创建二叉排序树
*/
void CreateBST(BSTree *pRoot)
{
    int data;
    scanf("%d",&data);
    if(data == 0)
        pRoot = NULL;
    else
    {
        *pRoot = (BSTree)malloc(sizeof(BSTNode));
        if(*pRoot == NULL)
            exit(EXIT_FAILURE);
        (*pRoot)->data = data;
        (*pRoot)->left = NULL;
        (*pRoot)->right = NULL;
        CreateBST(&((*pRoot)->left));
        CreateBST(&((*pRoot)->right));
    }
}
  
/*
采用中序遍历的方式将二叉树转化为双向链表,
*pLas指向双向链表的最后一个节点
*/
void ConvertNode(BSTree pRoot,BSTree *pLast)
{
    if(pRoot == NULL)
        return;
      
    //先转化左子树
    if(pRoot->left != NULL)
        ConvertNode(pRoot->left,pLast);
  
    //将双向链表的最后一个节点与根节点连接在一起
    pRoot->left = *pLast;
    if(*pLast != NULL)
        (*pLast)->right = pRoot;
    *pLast = pRoot;
  
    //转换右子树
    if(pRoot->right != NULL)
        ConvertNode(pRoot->right,pLast);
}
  
/*
返回双向链表的头结点
*/
BSTree Convert(BSTree pRoot)
{
    if(pRoot == NULL)
        return NULL;
    if(pRoot->left==NULL && pRoot->right==NULL)
        return pRoot;
  
    BSTree pLast = NULL;
    ConvertNode(pRoot,&pLast);
      
    //返回头结点
    BSTree pHead = pLast;
    while(pHead->left != NULL)
        pHead = pHead->left;
  
    return pHead;
}
  
int main()
{
    int n;
    while(scanf("%d",&n) != EOF)
    {
        int i;
        for(i=0;i<n;i++)
        {
            BSTree pRoot = NULL;
            CreateBST(&pRoot);
            BSTree pHead = Convert(pRoot);
            while(pHead != NULL)
            {
                printf("%d ",pHead->data);
                pHead = pHead->right;
            }
  
            printf("\n");
            free(pRoot);
            pRoot = NULL;
        }
    }
    return 0;
}
/**************************************************************
    Problem: 1503
    User: tcals
    Language: C
    Result: Accepted
    Time:70 ms
    Memory:1704 kb
****************************************************************/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值