二叉树的中序遍历及应用:二叉搜索树转换成一个排序的双向链表、二叉搜索树的第K个结点(java实现)

二叉树的中序遍历递归及非递归实现

package com.li.traversal;

import java.util.Stack;

public class LDR {
    public static void main(String[] args) {
        TreeNode[] nodes = new TreeNode[10];
        //构造一颗完全二叉树
        for(int i=0;i<10;i++){
            nodes[i] = new TreeNode(i);
        }
        for(int i=0;i<10;i++) {
            if(2*i+1<10)
                nodes[i].left = nodes[2*i+1];
            if(2*i+2<10)
                nodes[i].right = nodes[2*i+2];

        }
        ldrRe(nodes[0]);
        System.out.println("***************");
        ldr(nodes[0]);


    }
    //中序遍历的递归实现:左子树、根节点、右子树
    public static void ldrRe(TreeNode root){
        if(root==null)
            return;
        //找到左子树的最左边结点
        ldrRe(root.left);
        System.out.println(root.value);
        //在遍历右子树时,依然是左子树、根节点、右子树的顺序
        ldrRe(root.right);

    }
    //中序遍历非递归实现
    public static void ldr(TreeNode root){
        if(root==null)
            return;
        Stack<TreeNode> stack = new Stack<>();
        while(!stack.isEmpty()|| root!=null){
           while(root!=null){
               stack.push(root);
               root = root.left;
           }
            if(!stack.isEmpty()){
                root = stack.pop();
                System.out.println(root.value);
                root = root.right;
            }

        }
    }

}
//结点结构
class TreeNode{
    int value;
    TreeNode left;
    TreeNode right;
    TreeNode(int value){
        this.value = value;
    }

}

二叉搜索树转换成一个排序的双向链表

牛客网

题目描述

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

思路

二叉搜索树的中序遍历结果就是排序好的序列,因此使用中序遍历思想,不同的是:中序遍历的打印语句变为结点指向调整语句

非递归实现代码(使用栈)

import java.util.*;
public class Solution { 
   public TreeNode Convert(TreeNode pRootOfTree) {
		 if(pRootOfTree==null)
            return null;
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode p = pRootOfTree;
        TreeNode pre = null;// 保存中序遍历序列的上一节点
        boolean isFirst = true;
        while(p!=null||!stack.isEmpty()){
            while(p!=null){
                stack.push(p);
                p = p.left;
            }
            //结点指向的调整
            if(isFirst){
                p = stack.pop();
                pRootOfTree = p;// 将中序遍历序列中的第一个节点记为root
                pre = pRootOfTree;
                isFirst = false;
            }else{
                 p = stack.pop();
                pre.right = p;
                p.left = pre;
                pre = p;
            }    
            p = p.right;
        }
        return pRootOfTree;
    }
   }

递归实现代码

public class Solution {
    TreeNode head = null;
    TreeNode tail = null;
    public TreeNode Convert(TreeNode pRootOfTree) {
       helper(pRootOfTree);
        return tail;
    }
    public  void helper(TreeNode pRootOfTree){
         if(pRootOfTree==null)
            return ;
        helper(pRootOfTree.left);
        if(head==null){
            head = pRootOfTree;
            tail = head;
        }else{
            head.right = pRootOfTree;
            pRootOfTree.left = head;
            head = pRootOfTree;
        }
        helper(pRootOfTree.right);
    }
}

二叉搜索树的第K个结点

题目描述

给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。

思路

也是二叉树中序遍历的应用,将二叉树遍历的输出语句改动为符合题意即可。

代码

import java.util.*;
public class Solution {
    TreeNode KthNode(TreeNode pRoot, int k)
    {
        Stack<TreeNode> stack = new Stack<TreeNode>();
        int count = 0;
        if(pRoot==null)
            return pRoot;
        //非递归实现
        while(!stack.isEmpty() || pRoot!=null){
            while(pRoot!=null){
                stack.push(pRoot);
                pRoot = pRoot.left;
            }
            pRoot = stack.pop();
            count++;
            if(count==k)
                return pRoot;
            pRoot = pRoot.right;
            
        }
        return pRoot;
    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值