剑指offer——二叉搜索树与双向链表

剑指offer——二叉搜索树与双向链表

【题目描述】

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

【解题思路】

二叉搜索树的左孩子都比根节点小,右孩子都比根节点大。
举一个例子,按照题目要求变换二叉搜索树中节点指针,可以发现刚好是按照二叉树的中序遍历结果排序的。因此只需获得中序遍历的节点顺序,然后依次将上一个节点的右节点指向下一个节点,下一个节点的左孩子指向上一个节点。

重点:树的中序遍历

【代码实现】

import java.util.LinkedList;

/**
 * @Author: makexin
 * @Date: 2019/10/1713:15
 */
public class Solution {
    public TreeNode Convert(TreeNode pRootOfTree)
    {
        if (pRootOfTree == null)
            return null;
        LinkedList<TreeNode> queue = new LinkedList<>();
        midDFS(queue, pRootOfTree);
        TreeNode pre = queue.pop();
        TreeNode next, head = pre;
        while (!queue.isEmpty())
        {
            next = queue.pop();
            pre.right = next;
            next.left = pre;
            pre = next;
        }
        return head;
    }
    public void midDFS(LinkedList<TreeNode> queue, TreeNode root)
    {
        if (root!=null)
        {
            midDFS(queue, root.left);
            queue.add(root);
            midDFS(queue, root.right);
        }

    }
}

package 单双向链表; /** * 单向链表增删改查操作 * */ public class LinkTest { public static void main(String[] args) { Link l=new Link(); l.addNode("A"); l.addNode("B"); l.addNode("C"); l.addNode("D"); l.addNode("E"); l.printNode(); System.out.println("\n是否包含D:"+l.contains("D")); System.out.println("==========删除之前的内容=========="); l.printNode(); System.out.println("\n==========删除之后的内容=========="); l.deleteNode("A"); l.printNode(); } } class Link{//链表的完成类 class Node{//保存每个节点 private String data;//节点内容 private Node next;//下一个节点 public Node(String data){ this.data=data; } public void add(Node newNode) {//将节点加入到合适的位置 if(this.next==null){ this.next=newNode; }else{ this.next.add(newNode); } } public void print() {//输出节点的内容 System.out.print(this.data+"\t"); if(this.next!=null){ this.next.print();//递归调用输出 } } public boolean search(String data){//内部搜索的方法 if(data.equals(this.data)){ return true; }else{ if(this.next!=null){//向下继续判断 return this.next.search(data); }else{ return false; } } } public void delete(Node previous, String data) { if(data.equals(this.data)){//找到了匹配的节点 previous.next=this.next;//空出当前的节点 }else{ if(this.next!=null){ this.next.delete(this, data);//继续查找 } } } } private Node root;//链表中的根节点 public void addNode(String data){//增加节点 Node newNode=new Node(data); if(root==null){ root=newNode; }else{ root.add(newNode); } } public void printNode(){//链表的输出 if(root!=null){ root.print(); } } public boolean contains(String name){//判断元素是否存在 return this.root.search(name); } public void deleteNode(String data){//链表删除节点 if(this.contains(data)){ if(this.root.data.equals(data)){//如果是根节点 this.root=this.root.next;//修改根节点 }else{ this.root.next.delete(root,data);//把下一个节点的前节点和要删除的节点内容一起传入 } } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值