// Example 1-1 刪除單鏈表中全部重複元素 private static void removeRepeat(LinkList L) { Node node = L.head.next; // 首結點 while (node != null) // 一重循環,遍歷L中的每個元素 { // Object data=p.data; Node p = node; // q結點的前驅 Node q = p.next; // 與node數據相同的結點 while (q != null) // 二重循環,尋找相同結點 { if (node.data.equals(q.data)) { p.next = q.next; // 刪除q結點 } else { p = p.next; // 不相同時p結點後移,相同時p待在原位等待下一次比較 } q = q.next; // 不管相不相同q結點都要後移 } node = node.next; } }
第二種方法:java
// Example 1-1 書本代碼 private static void removeRepeatElem(LinkList L) throws Exception { Node p = L.head.next, q; // p爲首結點 while (p != null) { int order = L.indexOf(p.data); // 記錄下p的位置 q = p.next; while (q != null) { if (p.data.equals(q.data)) { L.remove(order + 1); // order+1即爲q結點的位置 } else { ++order; // 使得每次order都是q結點的前驅 } q = q.next; } p = p.next; } }
// Example 1-2 刪除全部數據爲x的結點,並返回數量,算法思想與1-1差很少 private static int removeAll(LinkList L, Object x) { Node p = L.head; Node q = p.next; int count = 0; while (q != null) { if (q.data.equals(x)) { p.next = q.next; count++; } else { p = p.next; } q = q.next; } return count; }
測試咱們的兩種算法的結果:node
算法1-1:算法
算法1-2:數據結構
// Example 2-1 實現對順序表的就地逆置 // 逆置:把(a1,a2,......,an)變成(an,an-1,...,a1) // 就地:逆置後的數據元素仍存儲在原來的存儲空間中 private static void reverseSqList(SqList L) { for (int i = 0; i < (int) (L.curLen / 2); i++) // 肯定循環次數,偶數爲長度的一半,奇數爲長度減一的一半,所以取curLen/2的整數 { //下面三個語句實現就地逆置 Object temp = L.listItem[i]; L.listItem[i] = L.listItem[L.curLen - 1 - i]; L.listItem[L.curLen - 1 - i] = temp; } }
// Example 2-2 實現對帶頭結點單鏈表的就地逆置 private static void reverseLinkList(LinkList L) throws Exception { Node p = L.head.next; L.head.next = null; while (p != null) { Node q=p.next; // q指向p的後繼,保留住後續結點 // 下面兩個語句實現頭插法,將p插入在位置爲0的地方 p.next=L.head.next; // p的後繼指向首結點 L.head.next=p; // 首結點指向p p = q; // p從新指向後續結點 } }
測試結果:測試
算法2-1:3d
算法2-2:code
// Example 3-1 實如今非遞減的有序整型單鏈表中插入一個值爲x的數據元素,並使單鏈表仍保持有序 private static void insertOrder(LinkList L, int x) { Node p = L.head.next; // 首結點 Node q = L.head; // p的前驅 while (p != null && Integer.valueOf(p.data.toString()) < x) // 當結點p的值大於等於x時跳出while { q = q.next; p = p.next; } Node s = new Node(x); s.next = p; q.next = s; }
// Example 3-2 實現將兩個非遞減鏈表LA和LB合併排列成一個新的非遞減鏈表LA private static LinkList mergeList(LinkList LA, LinkList LB) throws Exception { Node pa = LA.head.next; // LA首結點 Node pb = LB.head.next; // LB首結點 // LA.head.next = null; // 置空LA鏈表,這話寫與不寫都不影響插入 Node tail = LA.head; // 指向新鏈表LA的最後一個結點 while (pa != null && pb != null) { // 使用尾插法,按照非遞減順序插入,而且不須要插入時不須要將pa或pb指向null,由於最後插入的結點必定是null if (Integer.valueOf(pa.data.toString()) < Integer.valueOf(pb.data.toString())) { // 若pa.data小於pb.data則將pa插在尾結點後,而且繼續比較pa後續結點,直到出現大於等於pb的結點爲止 tail.next = pa; tail = pa; // tail後移 pa = pa.next; // 使得pa從新指向後續結點 } else { // 若pa.data大於等於pb.data則將pb插在pa的前面,而且繼續比較pb後續結點,直到出現大於pa的結點爲止 tail.next = pb; tail = pb; // tail後移 pb = pb.next; // 使得pb從新指向後續結點 } } tail.next = (pa != null ? pa : pb); return LA; }
測試結果:blog
算法3-1:rem
算法3-2:io
以上即是基於線性表的簡單算法,此係列後面會陸續介紹更多有關數據結構的內容,也會更新一些關於數據結構的算法題目例子,謝謝你們支持!