Moderate BST转双向链表 @CareerCup

书中提到了3种方法:

1 新建一个数据结构NodePair用于保存一个双向链表的头尾节点

2 不用NodePair,只用记录双向链表的头结点,尾节点可以遍历得到

3 形成一个循环链表,这样能更快地找到尾节点



package Moderate;


/**
 *  Consider a simple node-like data structure called BiNode, which has pointers to two
other nodes. The data structure BiNode could be used to represent both  a binary
tree (where nodel is the left node and node2 is the right  node) or a doubly  linked
list (where nodel  is the previous node and node2 is the next node). Implement  a
method to convert a binary  search tree (implemented  with BiNode) into a doubly
linked list. The values should be kept in order and the operation should be performed
in place (that is, on the original  data structure).

 现在有一个数据结构BiNode,它有两个指针。BiNode可以用来事先二叉树或者双向链表。
 要求实现一个方法来把一个BST转换成双向链表。要求保持顺序,并in place(即只能在
 原来的结构上操作,不能用多余的内存)
 
 
 *
 */
public class S17_13 {

	// ======================================== Solution 1
	private static class NodePair {
		BiNode head;
		BiNode tail;

		public NodePair(BiNode head, BiNode tail) {
			this.head = head;
			this.tail = tail;
		}
	}

	public static NodePair convert(BiNode root) {
		if (root == null) {
			return null;
		}

		NodePair part1 = convert(root.node1);
		NodePair part2 = convert(root.node2);

		if (part1 != null) {
			concat(part1.tail, root);
		}

		if (part2 != null) {
			concat(root, part2.head);
		}

		return new NodePair(part1 == null ? root : part1.head,
				part2 == null ? root : part2.tail);
	}

	public static void concat(BiNode x, BiNode y) {
		x.node2 = y;
		y.node1 = x;
	}

	// ======================================Solution 2: Without using
	// additional DS, use retrieving the tail
	static int count = 0;

	public static BiNode convert2(BiNode root) {
		if (root == null) {
			return null;
		}

		BiNode part1 = convert2(root.node1);
		BiNode part2 = convert2(root.node2);

		if (part1 != null) {
			concat(getTail(part1), root);
		}

		if (part2 != null) {
			concat(root, part2);
		}

		return part1 == null ? root : part1;
	}

	public static BiNode getTail(BiNode node) {
		if (node == null) {
			return null;
		}
		while (node.node2 != null) {
			count++;
			node = node.node2;
		}
		return node;
	}

	// ======================================= Solution 3: Use Circular Linked
	// List
	public static BiNode convertToCircular(BiNode root) {
		if (root == null) {
			return null;
		}

		BiNode part1 = convertToCircular(root.node1);
		BiNode part3 = convertToCircular(root.node2);

		if (part1 == null && part3 == null) {
			root.node1 = root;
			root.node2 = root;
			return root;
		}
		BiNode tail3 = part3 == null ? null : part3.node1;

		/* join left to root */
		if (part1 == null) {
			concat(part3.node1, root);
		} else {
			concat(part1.node1, root);
		}

		/* join right to root */
		if (part3 == null) {
			concat(root, part1);
		} else {
			concat(root, part3);
		}

		/* join right to left */
		if (part1 != null && part3 != null) {
			concat(tail3, part1);
		}

		return part1 == null ? root : part1;
	}

	public static BiNode convert3(BiNode root) {
		BiNode head = convertToCircular(root);
		head.node1.node2 = null;
		head.node1 = null;
		return head;
	}

	// =======================================Helper Methods

	public static void printLinkedListTree(BiNode root) {
		for (BiNode node = root; node != null; node = node.node2) {
			if (node.node2 != null && node.node2.node1 != node) {
				System.out.print("inconsistent node: " + node);
			}
			System.out.print(node.data + "->");
		}
		System.out.println();
	}

	public static BiNode createTree() {
		BiNode[] nodes = new BiNode[7];
		for (int i = 0; i < nodes.length; i++) {
			nodes[i] = new BiNode(i);
		}
		nodes[4].node1 = nodes[2];
		nodes[4].node2 = nodes[5];
		nodes[2].node1 = nodes[1];
		nodes[2].node2 = nodes[3];
		nodes[5].node2 = nodes[6];
		nodes[1].node1 = nodes[0];
		return nodes[4];
	}

	public static void printAsTree(BiNode root, String spaces) {
		if (root == null) {
			System.out.println(spaces + "- null");
			return;
		}
		System.out.println(spaces + "- " + root.data);
		printAsTree(root.node1, spaces + "   ");
		printAsTree(root.node2, spaces + "   ");
	}

	public static void main(String[] args) {
		BiNode root = createTree();
		printAsTree(root, "");
		// NodePair n = convert(root);
		// printLinkedListTree(n.head);
//		printLinkedListTree(convert2(root));
		printLinkedListTree(convert3(root));
	}

	static class BiNode {
		public BiNode node1; // 左或前指针
		public BiNode node2; // 右或后指针
		public int data;

		public BiNode(int d) {
			data = d;
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值