Moderate BST转双向链表 @CareerCup

原创 2013年12月04日 01:40:44

书中提到了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;
		}
	}
}


相关文章推荐

微软面试百题001——BST转化有序双向链表

微软面试百题001题解,超详细的解释内容,算法实现,以及本博主倾力打造的BST总结连接,绝对让想学之人有所学,言简意赅,赚的就是回头客...

1. BST树转化为双向链表

/* * -*- coding: utf-8 -*- * micro.cpp * * Created on: 2014年3月31日 * Author: szk * t...

双向链表源码.(C、C++、JAVA)

  • 2017年01月21日 21:57
  • 8KB
  • 下载

算法-二叉树转双向链表

1.首先看二叉树和双向链表的结构体: 双向链表存储结构如下: typedef struct DulNode{ ElemType data; struct DulNode *...

双向链表实现

  • 2014年12月05日 09:59
  • 2KB
  • 下载

异或指针双向链表

  • 2016年12月16日 19:09
  • 14KB
  • 下载

[转]C++实现双向链表

双向链表实现,通过C++实现/* ***h文件** */ #ifndef LinkList_hpp #define LinkList_hpptypedef struct Node{ int d...

双向链表的操作

  • 2014年02月28日 19:25
  • 5KB
  • 下载

数据结构---双向链表的实现

  • 2012年08月17日 23:24
  • 2KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Moderate BST转双向链表 @CareerCup
举报原因:
原因补充:

(最多只允许输入30个字)