遞迴和非遞迴方式合併有序連結串列
阿新 • • 發佈:2019-02-01
給定兩個有序單鏈表,合併成一個新的有序連結串列,分別用遞迴和非遞迴的方式實現如下:
package algorithm; public class MergeSortLinkList { public static void main(String[] args) { Node[] nodes = createData(); // Node node = mergeByRecursion(nodes[0], nodes[1]); Node node = merge(nodes[0], nodes[1]); print(node); } public static Node[] createData() { Node node1 = new Node(0, null); Node head1 = node1; Node node2 = new Node(0, null); Node head2 = node2; for (int i = 1; i <= 10; i++) { Node tmp1 = new Node(i, null); node1.next = tmp1; node1 = tmp1; } for (int i = 1; i <= 1000; i++) { Node tmp2 = new Node(i, null); node2.next = tmp2; node2 = tmp2; } Node[] nodes = new Node[2]; nodes[0] = head1; nodes[1] = head2; return nodes; } public static Node mergeByRecursion(Node node1, Node node2) { if (node1 == null) { return node2; } else if (node2 == null) { return node1; } if (node1.value < node2.value) { node1.next = merge(node1.next, node2); return node1; } else { node2.next = merge(node2.next, node1); return node2; } } public static Node merge(Node node1, Node node2) { if (node1 == null) { return node2; } else if (node2 == null) { return node1; } //先得到頭部指標 Node node = null; if (node1.value < node2.value) { node = node1; node1 = node1.next; } else { node = node2; node2 = node2.next; } //儲存頭部指標 Node head = node; //迴圈移動節點 while (node1 != null && node2 != null) { if (node1.value < node2.value) { node.next = node1; node = node1; node1 = node1.next; } else { node.next = node2; node = node2; node2 = node2.next; } } //當兩個連結串列長度不一致時的處理 if (node1 == null) { node.next = node2; } else { node.next = node1; } return head; } public static void print(Node node) { while (node != null) { System.out.println(node.value); node = node.next; } } } class Node { public int value; public Node next; public Node(int value, Node next) { this.value = value; this.next = next; } }
遞迴方法實現更加優雅,但缺陷在於限制了連結串列長度,否則會存在棧溢位的問題。