算法练习篇之:二叉搜索树与双向链表(树、链表)

算法练习篇之:二叉搜索树与双向链表(树、链表)

题目描述

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

解题思路

题目给定二叉搜索树,二叉搜索树定义:左子树的值<根节点的值<右子树的值。如果保持链表为有序状态,那么需要借助中序遍历(左跟右),正符合二叉搜索树的特性,转换为链表后指向左子节点的指针调整为****指向前一个节点指向右子节点的指针调整指向后一个节点。
具体实施看代码,有详细的注释!

图示

在这里插入图片描述

代码实现

博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

import java.util.Stack;

class TreeNode{  //定义二叉树的节点
    TreeNode father;
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(TreeNode left,TreeNode right){
        this.left=left;
        this.right=right;
    }
    TreeNode(int val){
        this.val=val;
    }
    TreeNode(){}
}

public class bsfConvertToLinkList {
    //将二叉搜索树转换为双向链表
    public TreeNode convert(TreeNode pRoot){//非递归
        TreeNode head=null;
        TreeNode pre=null;
        Stack<TreeNode> stack = new Stack<>();
        while (pRoot!=null||!stack.isEmpty()){
            while (pRoot!=null){//遍历到最左侧的节点
                stack.push(pRoot);
                pRoot=pRoot.left;
            }
            pRoot=stack.pop();//将叶子节点弹出,
                              // 在下次循环中将会弹出上个叶子节点的父节点,
                              //进而为下面插入父节点的右子节点做准备
            if (head==null){//首次建立链表
                head=pRoot;
                pre=pRoot;
            }else{//之后每次将节点插入到链表中去
                pre.right=pRoot;
                pRoot.left=pre;
                pre=pRoot;
            }
            pRoot=pRoot.right;//遍历当前节点的右子节点,如果该节点为叶子节点,则会为null,
            // 下面栈将会弹出当前该节点的父节点,随后在弹出的父节点再次执行到此处时,将会遍历其右子节点
        }
        return head;
    }
    public static void main(String[] args) {
        TreeNode node1=new TreeNode(10);
        TreeNode node2=new TreeNode(6);
        TreeNode node3=new TreeNode(14);
        TreeNode node4=new TreeNode(4);
        TreeNode node5=new TreeNode(8);

        node1.left=node2;node1.right=node3;
        node2.left=node4;node2.right=node5;
        node3.left=null;node3.right=null;
        node4.left=null;node4.right=null;
        node5.left=null;node5.right=null;

        bsfConvertToLinkList test=new bsfConvertToLinkList();
        TreeNode linkNode=test.convert(node1);
        System.out.println(linkNode.val+","+linkNode.right.val+","+linkNode.right.right.val);
    }
}



class Solution {//另外一种写法,比较好理解
    public Node treeToDoublyList(Node root) {
        if (root==null){
            return null;
        }
        ArrayList<Node> list=inorder(root);
        Node head=list.get(0);
        Node pre=head;
        for (int i=1;i<list.size();i++){
            Node node=list.get(i);
            pre.right=node;
            node.left=pre;
            pre=pre.right;
        }
        pre.right=head;
        head.left=pre;
        return head;
    }

    public ArrayList<Node> inorder(Node root){
        ArrayList<Node> list=new ArrayList<Node>();
        Stack<Node> stack=new Stack<Node>();
        Node cur=root;
        while (cur!=null||!stack.isEmpty()){
            while (cur!=null){
                stack.push(cur);
                cur=cur.left;
            }
            cur=stack.pop();
            list.add(cur);
            cur=cur.right;
        }
        return list;
    }
}

总结

本题来源于面试经典教材《剑指offer》中 归属于二叉树类型题目。
同许多在算法道路上不断前行的人一样,不断练习,修炼自己!
如有博客中存在的疑问或者建议,可以在下方留言一起交流,感谢各位!
最后,感谢AIAS!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值