书中提到了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; } } }
作者:hellobinfeng 发表于2013-12-4 1:40:44 原文链接
阅读:227 评论:0 查看评论