資料結構之單鏈表的幾個簡單演算法題
阿新 • • 發佈:2019-02-13
單鏈表作為最基本的資料結構,在程式設計中有著非常重要的運用。最近自己閒下來,正在整理資料結構和演算法的一些程式題,現將自己的程式碼貼出來與大家分享。如有不對之處,請大家指正。(好吧 ,這麼簡單的題目應該不會有錯,都測試過了。況且說的好像很多人看我部落格一樣。好久沒更,都長草了……就當做寫給自己看的吧。:P)
package test; import java.util.Hashtable; class LinkNode{ int value; LinkNode next; public LinkNode(int d){ value = d; } public LinkNode(int d, LinkNode n){ value = d; next = n; } /** * 列印連結串列 */ public static void printLinkedList(LinkNode head){ LinkNode p = head; while( null != p ){ System.out.print("" + p.value + " "); p = p.next; } System.out.println(); } } /** * LinkNodeOperation * 1.刪除連結串列中重複的節點 * 2.找出單鏈表中倒數的第K個元素 * 3.實現單鏈表的反轉 * 4.實現單鏈表逆向輸出 * 5.尋找單鏈表中間節點 * 6.判斷兩條連結串列是否相交 */ public class LinkNodeOperation { public static void main(String[] args){ // 生成一條連結串列: LinkNode n4 = new LinkNode(19,null); LinkNode n3 = new LinkNode(20,n4); LinkNode n2 = new LinkNode(30,n3); LinkNode n1 = new LinkNode(40,n2); LinkNode head1 = new LinkNode(50,n1); // 生成一條值為0-20的連結串列,頭結點為2: LinkNode head = new LinkNode(2); LinkNode cur = null; for( int i=1; i<19; i++) { LinkNode temp = new LinkNode(i); if( i==1 ) { head.next = temp; } else{ cur.next = temp; } cur = temp; } cur.next = n4; //列印原始連結串列: System.out.print("原始連結串列:"); LinkNode.printLinkedList(head); //列印原始連結串列: System.out.print("待判斷連結串列:"); LinkNode.printLinkedList(head1); //判斷兩條連結串列是否相交: System.out.println("是否相交:"+ LinkNodeOperation.isIntersect(head, head1)); //尋找連結串列的中間節點: System.out.print("連結串列的中間節點:"); LinkNodeOperation.findMiddleElem(head); //從尾到頭輸出: System.out.print("從尾到頭輸出單鏈表:"); LinkNodeOperation.printLinklistReversely(head); System.out.println(); //列印倒數第K個節點: LinkNodeOperation.findElem(head, 4); System.out.println("----------------------------------------"); LinkNodeOperation.findElem2(head, 4); System.out.println("----------------------------------------"); //列印去重後的連結串列: System.out.print("去重後的連結串列:"); LinkNodeOperation.deleteDuplicate2(head); //列印反轉後的連結串列 LinkNode.printLinkedList(head); System.out.print("反轉後的連結串列:"); LinkNodeOperation.reverseElem(head); } /** * 使用HashTable去重 */ public static void deleteDuplicate(LinkNode head){ Hashtable<Integer, Integer> hashTable = new Hashtable<Integer, Integer>(); LinkNode tmp = head; LinkNode pre = null; while(tmp != null){ if(hashTable.containsKey(tmp.value)){ pre.next = tmp.next; }else{ hashTable.put(tmp.value, 1); pre = tmp; } tmp = tmp.next; } } /** * 使用常規方法:雙重迴圈遍歷 */ public static void deleteDuplicate2(LinkNode head){ LinkNode p = head; while(p!=null){ LinkNode q = p; while(q.next!=null){ if(p.value == q.next.value){ q.next = q.next.next; } else{ q = q.next; } } p = p.next; } } /** * 找出倒數第K個元素 * 方法1兩次遍歷 */ public static void findElem(LinkNode head,int k){ int count = 1; int index = 0; LinkNode p = head; while(p.next!= null){ count++; p = p.next; } if( k<1 || k>count ){ return; } System.out.println("--------------------------------"); System.out.println("連結串列長度為:"+ count); while( head != null){ index++; if(index == count-k+1){ break; } head = head.next; } System.out.println("倒數第" + k + "個節點為:" + head.value); } /** * 找出倒數第K個元素 * 方法2 雙指標 只需一次遍歷 */ public static void findElem2(LinkNode head, int k){ if(k<1){ return; } LinkNode p = head; LinkNode q = head; // 讓P比Q先走K-1步 for(int i=1; i<=k-1; i++){ p = p.next; } while(p.next != null){ p = p.next; q = q.next; } System.out.println("倒數第" + k +"個節點是:" + q.value ); } /** * 連結串列反轉 */ public static void reverseElem(LinkNode head){ LinkNode pre = head; LinkNode cur = head.next; LinkNode next= null; while(null != cur){ next = cur.next; cur.next = pre; pre = cur; cur = next; } head.next = null; head = pre; LinkNode.printLinkedList(head); } /** * 從尾到頭輸出單鏈表 * 方法:遞迴 */ public static void printLinklistReversely(LinkNode head){ if(head != null){ printLinklistReversely(head.next); System.out.print(""+head.value+" "); } } /** * 尋找單鏈表的中間節點 */ public static void findMiddleElem(LinkNode head){ LinkNode p = head; LinkNode q = head; while(p!=null && p.next!=null && p.next.next!=null ){ p = p.next.next; q = q.next; } System.out.println(""+q.value); } /** * 判斷兩條連結串列是否相交 */ public static boolean isIntersect(LinkNode h1, LinkNode h2){ if (h1==null || h2==null) { return false; } LinkNode tail1 = h1; LinkNode tail2 = h2; while(tail1.next!=null){ tail1 = tail1.next; } while(tail2.next!=null){ tail2 = tail2.next; } return tail1==tail2; } }
執行結果: