题目16:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。链表定义如下:
public class Node<T> {
public T item;
public Node<T> next;
public Node() {
}
public Node(T item) {
this.item = item;
}
}
分析:
为了正确地反转链表,需要调整链表中指针的方向。如下图所示:
在图(a)中,h、i、j三个结点是相邻的,假设经过若干操作,我们已经把结点h之前的指针调整完毕,接下来我们把i的next指向h,此时链表结构如(b)所示。此时i、j之间断裂,为了避免这种情况,需要在调整结点i的next之前,把结点j保存起来。因此在调整之前,我们除了需要知道当前结点,还需要知道它的前一个结点以及后一个结点。
此外还需要注意一下几种情况:
1)输入链表的头指针为null,或者链表只有一个结点。
2)反转后的链表出现断裂。
3)返回的反转之后的头结点不是原始链表的尾结点。
代码如下所示:
public static Node reverseNodeList(Node pNode) {
Node result = null;
Node concurNode = pNode;
Node preNode = null;
while (concurNode != null) {
Node nextNode = concurNode.next;
if (nextNode == null) result = concurNode;
concurNode.next = preNode;
preNode = concurNode;
concurNode = nextNode;
}
return result;
}
public static void main(String[] args) {
Node<Integer> a = new Node<>(1);
Node<Integer> b = new Node<>(2);
Node<Integer> c = new Node<>(3);
Node<Integer> d = new Node<>(4);
Node<Integer> e = new Node<>(5);
Node<Integer> f = new Node<>(6);
a.next = b;
b.next = c;
c.next = d;
d.next = e;
e.next = f;
// 含有多个结点
// Node node = reverseNodeList(a);
// 仅含有一个结点
// Node node = reverseNodeList(new Node(2));
// 头结点为空
Node node = reverseNodeList(null);
while (node != null) {
System.out.print(node.item + " ");
node = node.next;
}
}
题目17:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。链表结点定义和上一题一致。
分析:
分析从合并两个链表的头结点开始。链表1的头结点的值小于链表2的头结点的值,因此链表1的头结点将是合并后链表的头结点。如下图所示。
在剩余的结点中,链表2的头结点的值小于链表1的头结点的值,因此链表2的头结点是剩余结点的头结点,把这个结点和之前已经合并好的链表的尾结点链接在一起。如下图所示,以此类推。
此外还要对空链表单独处理,当第一个链表为空链表时,那么第二个链表就是合并之后的结果;当第二个链表为空链表时,那么第一个链表就是合并之后的结果;当两个链表都为空时,合并后的链表也为空。
代码如下所示:
public static Node merge(Node pNode1, Node pNode2) {
if (pNode1 == null) return pNode2;
else if (pNode2 == null) return pNode1;
Node result = null;
if ((Integer) pNode1.item < (Integer) pNode2.item) {
result = pNode1;
result.next = merge(pNode1.next, pNode2);
} else {
result = pNode2;
result.next = merge(pNode1, pNode2.next);
}
return result;
}
public static void main(String[] args) {
Node<Integer> a = new Node<>(1);
Node<Integer> b = new Node<>(3);
Node<Integer> c = new Node<>(5);
Node<Integer> d = new Node<>(7);
Node<Integer> e = new Node<>(9);
a.next = b;
b.next = c;
c.next = d;
d.next = e;
Node<Integer> f = new Node<>(2);
Node<Integer> g = new Node<>(4);
Node<Integer> h = new Node<>(6);
Node<Integer> i = new Node<>(8);
Node<Integer> j = new Node<>(10);
f.next = g;
g.next = h;
h.next = i;
i.next = j;
// Node node = merge(a,f);
// 有一个链表为空
// Node node = merge(null,f);
// 两个链表都只含有一个结点
Node node = merge(new Node<>(10), new Node<>(12));
while (node != null) {
System.out.print(node.item + " ");
node = node.next;
}
}