先說一下線性表。
線性表:在邏輯上,數據是連續的。線性表有兩種存儲方式:順序存儲方式和鏈式存儲方式。
數組(array):數組就是線性表的順序存儲方式。數組的內存是連續分配的,並且是靜態分配的,即在使用數組之前需要分配固定大小的空間。
鏈表(linked-list):鏈表就是線性表的鏈式存儲方式。鏈表的內存是不連續的,前一個元素存儲地址的下一個地址中存儲的不一定是下一個元素。鏈表通過一個指向下一個元素地址的引用將鏈表中的元素串起來。
鏈表分爲單鏈表,雙向鏈表和循環鏈表。在這裏只寫了單向鏈表的各種操作。
單鏈表的實現
public class ListNode {
int val;
ListNode next;
ListNode( int x ) { this.val = x; };
}
- 後插法:
public ListNode insert(ListNode head,int value) {
ListNode t = new ListNode(value);
t.next = head;
return t;
}
- 反轉鏈表
public ListNode reverseLinkedList(ListNode head) {
ListNode ReverseHead = null;
ListNode t = null;
while ( head!=null ) {
t = head.next;
head.next = ReverseHead;
ReverseHead = head;
head = t;
}
return ReverseHead;
}
- 獲取中間結點
public ListNode getMiddle(ListNode head) {
if ( head==null || head.next==null ) return head;
ListNode slow = head,fast = head;
while( fast.next!=null && fast.next.next!=null ) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
- 獲取倒數第k個結點
public ListNode findLastK( ListNode head,int k) {
ListNode p1 = head;
ListNode p2 = head;
for ( int i=0; i<k; i++ ) {
if ( p2==null ) {
return null;
}
p2 = p2.next;
}
while ( p2!=null ) {
p1 = p1.next;
p2 = p2.next;
}
return p1;
}
- 判斷是否有環
public boolean isLoop(ListNode head) {
boolean flag = false;
ListNode slow = head,
fast = head;
while ( fast!=null && fast.next!=null ) {
fast = fast.next;
slow = slow.next;
if ( slow==fast ) {
flag = true;
break;
}
}
return flag;
}
- 尋找環的起點
public ListNode finsLoopStart( ListNode head ) {
ListNode slow = head,
fast = head;
while ( fast!=null && fast.next!=null ) {
fast = fast.next.next;
slow = slow.next;
if ( fast==slow ) break;
}
if ( fast==null || fast.next==null )
return null;
else {
slow = head;
while ( slow!=fast ) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
7.刪除重複結點
public void deleteListNode ( ListNode head ) {
ListNode p = head,
q = null;
while ( p!=null ) {
q = p.next;
while ( q!=null && q.val==p.val ) {
q = q.next;
}
p.next = q;
p = p.next;
}
}