問題
將兩個有序單鏈表A和B,合併成C,如下圖。
解決思路
同時從兩個鏈表的頭節點開始遍歷,比較當前節點大小,將小的節點添加到C鏈表中,然後遍歷。
非遞歸寫法
/**
* 鏈表ADT
*
* @author wangtao
* @param <T>
*/
public class LinkADT<T> {
/**
* 單鏈表節點
*
* @author wangtao
* @param <T>
*/
private static class SingleNode<T> {
public SingleNode<T> next;
public T data;
public SingleNode(T data) {
this.data = data;
}
public T getNextNodeData() {
return next != null ? next.data : null;
}
}
/**
* 有序鏈表合併,非遞歸
*
* @param nodeA
* @param nodeB
* @return
*/
public static SingleNode<Integer> mergeV1(SingleNode<Integer> nodeA, SingleNode<Integer> nodeB) {
if (nodeA == null) {
return nodeB;
} else if (nodeB == null) {
return nodeA;
}
// 初始化nodeC
SingleNode<Integer> nodeC = new SingleNode<Integer>(null);
// 定義當前節點
SingleNode<Integer> currentNode = nodeC;
// 遍歷A和B,直到末尾
while (nodeA != null || nodeB != null) {
SingleNode<Integer> nextNode = new SingleNode<Integer>(null);
// 找出較小的節點
if (compareNode(nodeA, nodeB) <= 0) {
nextNode.data = nodeA.data;
nodeA = nodeA.next;
} else {
nextNode.data = nodeB.data;
nodeB = nodeB.next;
}
// 添加較小的節點
currentNode.next = nextNode;
currentNode = currentNode.next;
}
// 去掉沒有用的頭結點
nodeC = nodeC.next;
return nodeC;
}
private static int compareNode(SingleNode<Integer> node1, SingleNode<Integer> node2) {
if (node1 == null) {
return 1;
} else if (node2 == null) {
return -1;
}
if (node1.data == null) {
return -1;
} else if (node2.data == null) {
return 1;
}
return node1.data.compareTo(node2.data);
}
}
這種不是很簡潔,尤其是最後還要去掉一個頭結點,感覺很累贅。
遞歸寫法
與前面重複的代碼就不貼了,直接上核心代碼。
/**
* 有序鏈表合併,遞歸
*
* @param nodeA
* @param nodeB
* @return
*/
private static SingleNode<Integer> mergeV2(SingleNode<Integer> nodeA, SingleNode<Integer> nodeB) {
SingleNode<Integer> result;
if (nodeA == null) {
return nodeB;
} else if (nodeB == null) {
return nodeA;
}
// 找出較小的節點
if (compareNode(nodeA, nodeB) <= 0) {
result = nodeA;
nodeA = nodeA.next;
} else {
result = nodeB;
nodeB = nodeB.next;
}
result.next = mergeV2(nodeA, nodeB);
return result;
}
遞歸的代碼看起來清爽很多,看起來也比較好理解。
完整代碼請參考:
https://github.com/wanf425/Algorithm/blob/master/src/com/wt/adt/LinkADT.java
博文地址:
https://www.taowong.com/blog/2018/10/14/data-strutctures-and-algorithm-03.html