剑指offer面试题27-二叉搜索树转双向链表

题目:

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

* */


然后基本要实现的功能就是这样子的:



怎么实现呢?

看着像递归,就拿根节点来看:

我要做两件事情:

1.拿到左边树的最大的,让root.left=max,max.right=root

2.拿到右边树的最小的,让root.right=min,min.left=root


所以就需要2个函数,min和max,分别处理最大和最小:

看代码:

package com.aii.algorithm;

public class ConvertBinaryTreeToLinkedList {

	/**
	 * 输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。<br/>
	 * 要求不能创建任何新的节点,只能调整树中节点指针的指向。<br/>
	 * 
	 * */
	public BinaryTreeNode convert(BinaryTreeNode root) {
		// 肯定是中序遍历

		if (root == null) {
			return null;
		}
		// 获取左节点的最大值,并且
		// 1.把最大值赋值给root的left
		// 2.把root赋值给最大值的right
		getMax(root, root.left);

		// 获取右节点的最小值,并且
		// 1.把最小值赋值给root的right
		// 2.把root赋值给最小值的left
		getMin(root, root.right);

		// 最后得到链表的头结点,返回
		BinaryTreeNode tmp = root;
		while (tmp.left != null) {
			tmp = tmp.left;
		}

		return tmp;
	}

	/**
	 * 处理左节点
	 * */
	private void getMax(BinaryTreeNode root, BinaryTreeNode left) {
		if (left == null) {
			return;
		}
		// 也做同样的处理
		getMax(left, left.left);
		getMin(left, left.right);

		// 找到最大的那个值
		BinaryTreeNode tmp = left;
		while (tmp.right != null) {
			tmp = tmp.right;
		}
		// 然后分配2个指针
		tmp.right = root;
		root.left = tmp;
	}

	/**
	 * 处理右节点
	 * */
	private void getMin(BinaryTreeNode root, BinaryTreeNode right) {
		if (right == null) {
			return;
		}

		getMax(right, right.left);
		getMin(right, right.right);

		// 找到最小的那个值,然后设置指针
		BinaryTreeNode tmp = right;
		while (tmp.left != null) {
			tmp = tmp.left;
		}
		tmp.left = root;
		root.right = tmp;
	}

}


测试用例:

package com.aii.algorithm;

import org.junit.Before;
import org.junit.Test;

public class ConvertBinaryTreeToLinkedListTest {

	private BinaryTreeNode root = new BinaryTreeNode(10);

	@Before
	public void init() {
		BinaryTreeNode n2 = new BinaryTreeNode(6);
		BinaryTreeNode n3 = new BinaryTreeNode(14);
		BinaryTreeNode n4 = new BinaryTreeNode(4);
		BinaryTreeNode n5 = new BinaryTreeNode(8);
		BinaryTreeNode n6 = new BinaryTreeNode(12);
		BinaryTreeNode n7 = new BinaryTreeNode(16);

		root.left = n2;
		root.right = n3;

		n2.left = n4;
		n2.right = n5;

		n3.left = n6;
		n4.right = n7;
	}

	@Test
	public void test() {
		BinaryTreeNode bt = new ConvertBinaryTreeToLinkedList().convert(root);
		print(bt);
	}

	private void print(BinaryTreeNode bt) {
		if (bt == null) {
			System.out.println(bt);
			return;
		}
		BinaryTreeNode tmp = bt;
		while (tmp.right != null) {
			System.out.print(tmp.value + "-->");
			tmp = tmp.right;
		}
		System.out.println(tmp.value);

		//
		while (tmp.left != null) {
			System.out.print(tmp.value + "-->");
			tmp = tmp.left;
		}
		System.out.println(tmp.value);
	}

}
打印结果:

4-->16-->6-->8-->10-->12-->14
14-->12-->10-->8-->6-->16-->4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值