zoukankan      html  css  js  c++  java
  • 剑指OFFER之二叉搜索树与双向链表(九度OJ1503)

    题目描述:

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

     

    输入:

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

     

    输出:

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

     

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

    解题思路:

      这道题应该是最近写的最繁琐的一道题了。

      首先输入按规则来,需要进行前序遍历输入

    void createTree(BTree **b){  
        int m;
        scanf("%d",&m);
        if(m == 0)
            *b = NULL;
        else{
            BTree *s = (BTree *)malloc(sizeof(BTree));
            s->data = m;
            s->lchild = NULL;
            s->rchild = NULL;
            *b = s;
            createTree(&((*b)->lchild));
            createTree(&((*b)->rchild));
        }
    }

      另外,整体的思路,是用一个指针记录转换的双链表表尾。

      每次进行中序遍历的转换。

      最先转换的是最左下的节点,

    void converNode(BTree *b,BTree **p){
        if(b == NULL)
            return ;
        BTree *pnow = b;
        if(b->lchild != NULL)
            converNode(b->lchild,p);
        
        pnow->lchild = *p;
        if(*p != NULL)
            (*p)->rchild = pnow;
    
        *p = pnow;
    
        if(b->rchild != NULL)
            converNode(b->rchild,p);
    }

      每次遍历节点的左孩子右孩子。把左孩子指向转换链表的尾节点,并把末尾指针的右孩子指向自己。右孩子指向节点的右孩子。如果没有右孩子就返回。下面是代码思路的步骤:

    1 找到最左边也就是最小的节点,PLast = NULL;

    2 让节点的左孩子指向链尾,然后链尾指针右移。如果右孩子为空就返回。

    最后我们从尾遍历回头指针返回。

    全部代码:

    #include <stdio.h>
    #include <stdlib.h>
    typedef struct btree{
        int data;
        struct btree *lchild,*rchild;
    }BTree;
     
    void createTree(BTree **b);
    void inorderTree(BTree *b);
    BTree * convert(BTree *b);
    void converNode(BTree *b,BTree **p);
     
    int main(){
        int n;
        scanf("%d",&n);
        while(n--){
            BTree *b = (BTree *)malloc(sizeof(BTree));   
            createTree(&b);
            BTree *head = convert(b);
            while(head!=NULL){
                printf("%d ",head->data);
                head = head->rchild;
            }
            printf("
    ");
        }
        return 0;
    }
    BTree* convert(BTree *b){
        BTree *pLast = NULL;
        converNode(b,&pLast);
     
        BTree *phead = pLast;
        while(phead != NULL && phead->lchild != NULL)
            phead = phead->lchild;
        return phead;
    }
    void converNode(BTree *b,BTree **p){
        if(b == NULL)
            return ;
        BTree *pnow = b;
        if(b->lchild != NULL)
            converNode(b->lchild,p);
         
        pnow->lchild = *p;
        if(*p != NULL)
            (*p)->rchild = pnow;
     
        *p = pnow;
     
        if(b->rchild != NULL)
            converNode(b->rchild,p);
    }
    void createTree(BTree **b){  
        int m;
        scanf("%d",&m);
        if(m == 0)
            *b = NULL;
        else{
            BTree *s = (BTree *)malloc(sizeof(BTree));
            s->data = m;
            s->lchild = NULL;
            s->rchild = NULL;
            *b = s;
            createTree(&((*b)->lchild));
            createTree(&((*b)->rchild));
        }
    }
    /**************************************************************
        Problem: 1503
        User: xhalo
        Language: C
        Result: Accepted
        Time:80 ms
        Memory:1704 kb
    ****************************************************************/
  • 相关阅读:
    字集码(字符编码)
    图片轮播(可实现手动与自动的切换)
    Eclipse常用快捷键
    Java并发编程:Callable、Future和FutureTask
    Java并发之CountDownLatch、CyclicBarrier和Semaphore
    java注解
    JVM加载class原理
    阿里中间件技术及双十一实践--软负载——分布式系统的引路人
    阿里中间件技术及双十一实践--中间件总体介绍
    Java的LockSupport.park()实现分析
  • 原文地址:https://www.cnblogs.com/xing901022/p/3781713.html
Copyright © 2011-2022 走看看