剑指offer24--搜素二叉树转双向链表

题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。

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


从上面可以看出,还是应该使用的递归的方式,现将左子树连接好,然后再将根节点连接,最后将右子树连接,要实现这样功能,创建一个类似于二级指针的结点,通过这个结点逐步将二叉树连接成双向链表。

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


public class Test27 {
    public static class BinaryTreeNode {
        int value;
        BinaryTreeNode left;
        BinaryTreeNode right;
    }
    
    public static BinaryTreeNode convert(BinaryTreeNode root) {


        // 用于保存处理过程中的双向链表的尾结点
        BinaryTreeNode [] lastNode = new BinaryTreeNode[1];
        convertNode(root, lastNode);


        // 找到双向链表的头结点
        BinaryTreeNode head = lastNode[0];
        while (head != null && head.left != null) {
            head = head.left;
        }
        return head;
    }


    /**
     * 链表表转换操作
     *
     * @param node     当前的根结点
     * @param lastNode 已经处理好的双向链表的尾结点,使用一个长度为1的数组,类似C++中的二级指针
     */
    public static void convertNode(BinaryTreeNode node, BinaryTreeNode lastNode[]) {
        // 结点不为空
        if (node != null) {


            // 如果有左子树就先处理左子树
            if (node.left != null) {
                convertNode(node.left, lastNode);
            }


            // 将当前结点的前驱指向已经处理好的双向链表的尾结点
            // 因为上面处理的是左子树
            // 这是一个向左指的过程
            node.left = lastNode[0];


            // 如果左子树转换成的双向链表不为空,设置尾结点的后继
            // 这样就可以将node结点连接到链表的末端
            // 这是一个向右指的过程
            if (lastNode[0] != null) {
                lastNode[0].right = node;
            }


            // 记录当前结点为尾结点
            lastNode[0] = node;


            // 处理右子树
            if (node.right != null) {
                convertNode(node.right, lastNode);
            }
        }
    }


    public static void main(String[] args) {
        test01();
    }


    private static void printList(BinaryTreeNode head) {
        while (head != null) {
            System.out.print(head.value + "->");
            head = head.right;
        }
        System.out.println("null");
    }


    private static void printTree(BinaryTreeNode root) {
        if (root != null) {
            printTree(root.left);
            System.out.print(root.value + "->");
            printTree(root.right);
        }
    }


    //            10
    //         /      \
    //        6       14
    //       /\        /\
    //      4  8     12  16
    private static void test01() {
        BinaryTreeNode node10 = new BinaryTreeNode();
        node10.value = 10;


        BinaryTreeNode node6 = new BinaryTreeNode();
        node6.value = 6;


        BinaryTreeNode node14 = new BinaryTreeNode();
        node14.value = 14;


        BinaryTreeNode node4 = new BinaryTreeNode();
        node4.value = 4;


        BinaryTreeNode node8 = new BinaryTreeNode();
        node8.value = 8;


        BinaryTreeNode node12 = new BinaryTreeNode();
        node12.value = 12;


        BinaryTreeNode node16 = new BinaryTreeNode();
        node16.value = 16;


        node10.left = node6;
        node10.right = node14;


        node6.left = node4;
        node6.right = node8;


        node14.left = node12;
        node14.right = node16;


        System.out.print("Before convert: ");
        printTree(node10);
        System.out.println("null");
        BinaryTreeNode head = convert(node10);
        System.out.print("After convert : ");
        printList(head);
    }


好好学习,天天递归


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值