在看剑指offer的时候看到有关链表基本操作的考点,想总结一下,基本是参考http://blog.csdn.net/kerryfish/article/details/24043099文章实现的,对于该文章中的方法进行了编写,测试,修改了其中几个问题。源码如下
package cn.com.cnn;
import java.util.Stack;
public class ListSum {
public static class Node {
int value;
Node next;
public Node(int value) {
this.next = null;
this.value = value;
}
}
public static void main(String[] args) {
int[] data1 = {1, 2, 3, 4, 5};
int[] data2 = {3, 4, 5};
ListSum listSum = new ListSum();
Node pHead = listSum.createList(data1);
Node merge = listSum.createList(data2);
//listSum.printList(pHead);
//System.out.println(listSum.reGetKthNode(pHead, 3));
//listSum.printList(listSum.reverseList(pHead));
//listSum.printList(listSum.reverseListRec(pHead));
//listSum.returnMiddNode(pHead);
//listSum.reversePrintListRec(pHead);
//listSum.reversePrintListStack(pHead);
//listSum.printList(listSum.mergeLists(pHead, merge));
//listSum.printList(listSum.deleteNode(pHead, 2));
//listSum.printList(listSum.firstCommonNode(pHead, merge));
}
public Node createList(int[] data) {
Node pHead = null;
Node temp = null;
for(int i = 0; i < data.length; i++) {
if(i == 0) {
pHead = new Node(data[i]);
temp = pHead;
continue;
}
temp.next = new Node(data[i]);
temp = temp.next;
}
return pHead;
}
public static int getListLength(Node pHead) {
int length = 0;
while(pHead != null) {
length++;
pHead = pHead.next;
}
return length;
}
//利用循环倒置链表
public Node reverseList(Node pHead) {
if(pHead == null || pHead.next == null ) {
return pHead;
}
Node pNext = null;
Node pPre = null;
while(pHead != null) {
pNext = pHead.next;
pHead.next = pPre;
pPre = pHead;
pHead = pNext;
}
return pPre;
}
//利用迭代倒置链表
public Node reverseListRec(Node pHead) {
if(pHead == null || pHead.next == null) {
return pHead;
}
Node pNext = reverseListRec(pHead.next);
pHead.next = pNext;
pHead = pHead.next;
return pNext;
}
//查找链表中间节点,两个指针一个一次跳两个,一个一次跳一个
public Node returnMiddNode(Node pHead) {
if(pHead == null || pHead.next == null) {
return pHead;
}
Node pMidd = pHead;
Node temp = pHead;
while(temp != null && temp.next != null) {
temp = temp.next.next;
pMidd = pMidd.next;
}
System.out.println(pMidd.value);
return pMidd;
}
public int reGetKthNode(Node pHead, int k) {
Node p = pHead;
if(pHead == null || k <= 0) {
return 0;
}
for(int i = 0; i < k; i++) {
p = p.next;
}
while(p.next != null) {
p = p.next;
pHead = pHead.next;
}
return pHead.value;
}
public void printList(Node pHead) {
if(pHead == null) {
System.out.println("null");
}
while(pHead != null) {
System.out.print(pHead.value + ", ");
pHead = pHead.next;
}
}
//从尾到头打印单链表,递归
public void reversePrintListRec(Node pHead) {
if(pHead == null) {
return;
} else {
reversePrintListRec(pHead.next);
System.out.print(pHead.value + " ");
}
}
//从尾到头打印单链表,栈
public void reversePrintListStack(Node pHead) {
Stack<Node> nodeStack = new Stack<Node>();
while(pHead != null) {
nodeStack.push(pHead);
pHead = pHead.next;
}
while(!nodeStack.empty()) {
System.out.print(nodeStack.pop().value + " ");
}
}
//合并两个有序的单链表l1,l2
public Node mergeLists(Node head1, Node head2) {
if(head1 == null) {
return head2;
} else if(head2 == null) {
return head1;
}
Node result = null;
Node temp = null;
if(head1.value < head2.value) {
temp = head1;
head1 = head1.next;
} else if(head1.value > head2.value) {
temp = head2;
head2= head2.next;
} else {
temp = head1;
head1 = head1.next;
head2 = head2.next;
}
result = temp;
while(head1 != null && head2 != null) {
if(head1.value < head2.value) {
temp.next =head1;
head1 = head1.next;
} else if(head1.value > head2.value) {
temp.next = head1;
head1= head1.next;
} else {
temp.next = head1;
head1 = head1.next;
head2 = head2.next;
}
temp = temp.next;
temp.next = null;
}
if(head1 == null) {
temp.next = head2;
}
if(head2 == null) {
temp.next = head1;
}
return result;
}
public Node deleteNode(Node pHead, int value) {
Node temp = null;
if(pHead == null) {
return temp;
}
temp = pHead;
if(temp.value == value) {
temp = temp.next;
pHead = temp;
} else {
while(temp.next != null && temp.next.value != value) {
temp = temp.next;
}
if(temp.next != null && temp.next.value == value) {
temp.next = temp.next.next;
}
}
return pHead;
}
//求两个链表的第一个公共节点
//如果仅仅判断两根链表是否交叉,直接看两个链表最后一个节点是不是相等就可以了。因为都是单链表
public Node firstCommonNode(Node list1, Node list2) {
Node result = null;
if(list1 == null || list2 == null) {
return result;
}
int list1Length = getListLength(list1);
int list2Length = getListLength(list2);
if(list1Length <= list2Length) {
for(int i = 0; i < list2Length - list1Length; i++) {
list2 = list2.next;
}
} else {
for(int i = 0; i < list1Length - list2Length; i++) {
list1 =list1.next;
}
}
while(list1 != null && list2 != null) {
if(list1.value == list2.value) {
result = list1;
result.next = null;
break;
} else {
list1 = list1.next;
list2 = list2.next;
}
}
return result;
}
//给出head,delete指针,O(1)时间复杂度删除delete。将删除节点和下个节点的值置换再删除
public Node deleteNode2(Node pHead, Node delete) {
Node result = null;
if(delete == null) {
return result;
}
if(delete.next == null) {
if(pHead == delete) {
return result;
} else {
Node temp = pHead;
while(temp.next != delete) {
temp = temp.next;
}
temp.next = null;
return pHead;
}
}
delete.value = delete.next.value;
delete.next = delete.next.next;
return result;
}
}