連結串列經典演算法題實現
阿新 • • 發佈:2019-02-01
本文包含連結串列的以下內容:
1、單鏈表的建立和遍歷
2、求單鏈表中節點的個數
3、查詢單鏈表中的倒數第k個結點(劍指offer,題15)
4、查詢單鏈表中的中間結點
5、合併兩個有序的單鏈表,合併之後的連結串列依然有序【出現頻率高】(劍指offer,題17)
6、單鏈表的反轉【出現頻率最高】(劍指offer,題16)
7、從尾到頭列印單鏈表(劍指offer,題5)
8、判斷單鏈表是否有環
9、取出有環連結串列中,環的長度
10、單鏈表中,取出環的起始點(劍指offer,題56)。本題需利用上面的第8題和第9題。
11、判斷兩個單鏈表相交的第一個交點(劍指offer,題37)
package com.he; import java.util.Stack; import com.he.LinkList.Node; public class test32 { class Node{ int data; Node next; Node(int data){ this.data = data; } } public Node head =null; public Node current = null; //新增節點 public void add(int data){ if(head==null){ head = new Node(data); current = head; }else{ current.next = new Node(data); current = current.next; } } //方法過載:向連結串列中新增結點 public void add(Node node){ if(head==null){ head = node; current = node; }else{ current.next = node; current = current.next; } } //遍歷節點 public void print(Node node){ current = node; while(current!=null){ System.out.println(current.data); current = current.next; } } //求單鏈表節點 public int getLength(Node node){ current = node; int length = 0; if(current == null){ return 0; } while(current!=null){ length++; current = current.next; } return length; } //查詢單鏈表中的倒數第k個結點 public Node findLastNode(Node node,int k){ if(node==null || k==0){ return null; } Node first = node; Node second = node; for (int i = 0; i < k-1; i++) { second = second.next; if(second == null){ return null; } } while(second.next!=null){ first = first.next; second = second.next; } return first; } //查詢單鏈表中的中間結點 public Node findMiddle(Node node){ if(node==null){ return null; } Node first = node; Node second = node; while(first!=null && second!=null){ if(second.next!=null){ second = second.next.next; }else{ return first; } first = first.next; } return first; } //合併兩個有序的單鏈表,合併之後的連結串列依然有序 public Node getMergeLinkList(Node head1,Node head2){ if(head1==null && head2==null){ return null; } if(head1==null){ return head2; } if(head2==null){ return head1; } Node head; Node current; if(head1.data < head2.data){ head = head1; current = head1; head1 = head1.next; }else{ head = head2; current = head2; head2 = head2.next; } while(head1!= null && head2!= null){ if(head1.data < head2.data){ current.next = head1; current = current.next; head1 = head1.next; }else{ current.next = head2; current = current.next; head2 = head2.next; } } if(head1 == null){ current.next = head2; } if(head2 == null){ current.next = head1; } return head; } //單鏈表的反轉 public Node reverseList(Node head){ if(head==null && head.next==null){ return head; } Node reverseHead = null; Node next = null; Node current = head; while(current!=null){ next = current.next; current.next = reverseHead; reverseHead = current; current = next; } return reverseHead; } //從尾到頭列印單鏈表 public void reversePrint(Node head){ if(head == null){ return; } Stack<Node> stack = new Stack<Node>(); Node current = head; while(current!=null){ stack.push(current); current = current.next; } while(stack.size()>0){ System.out.println(stack.pop().data); } } //判斷單鏈表是否有環 public boolean hasCycle(Node head){ if(head == null){ return false; } Node first = head; Node second = head; while(second!=null){ first = first.next; if(second.next!=null){ second = second.next.next; }else{ return false; } if(first == second){ return true; } } return false; } //取出有環連結串列中,環的長度 public int getCycleLength(Node node){ int length = 0; Node current = node; while(current!=null){ current = current.next; length++; if(current == node){ return length; } } return length; } //單鏈表中,取出環的起始點 public Node getCycleStart(Node head,int cycleLength){ if(head==null){ return null; } Node first = head; Node second = head; for (int i = 0; i < cycleLength; i++) { second = second.next; } while(first!=null&& second!=null){ if(first == second){ return first; } first = first.next; second = second.next; } return null; } //求兩個單鏈表相交的第一個交點 public Node getFirstCommonNode(Node head1,Node head2){ if(head1==null|| head2==null){ return null; } int length1 = getLength(head1); int length2 = getLength(head2); int lengthDif = 0; Node longHead = null; if(length1 > length2){ lengthDif = length1-length2; longHead = head1; }else{ lengthDif = length2-length1; longHead = head2; } for (int i = 0; i < lengthDif; i++) { longHead = longHead.next; } while(longHead!=null && head2!=null){ longHead = longHead.next; head2 = head2.next; if(longHead == head2){ return head2; } } return null; } public static void main(String[] args) { test32 sh = new test32(); for (int i = 0; i < 4; i++) { sh.add(i); } // sh.print(sh.head); // System.out.println(sh.getLength(sh.head)); // System.out.println(sh.findLastNode(sh.head, 3).data); //sh.print(sh.reverseList(sh.head)); sh.add(sh.head); System.out.println(sh.hasCycle(sh.head)); System.out.println(sh.hasCycle(sh.head)); System.out.println(sh.getCycleLength(sh.head)); System.out.println(sh.getCycleStart(sh.head, sh.getCycleLength(sh.head)).data); // test32 sh1 = new test32(); // for (int i = 6; i < 8; i++) { // sh1.add(i); // } // sh.print(sh.getMergeLinkList(sh.head, sh1.head)); } }