【線性表基礎】基於線性表的簡單算法【Java版】

本文描述了基於線性表的簡單算法及其代碼【Java實現】

1-1 刪除單鏈表中全部重複元素

// 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;
        }
    }

1-2 刪除全部數據爲x的結點,並返回數量,算法思想與1-1差很少

// 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:數據結構

2-1 試寫一算法,實現順序表的就地逆置,即利用原表的存儲空間將線性表(a1,a2…,an)逆置爲(an,an-1…,a1)

// 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;
        }
    }

2-2 實現對帶頭結點的單鏈表的就地逆置

// 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

3-1 實如今非遞減的有序整型單鏈表中插入一個值爲x的數據元素,並使單鏈表仍保持有序

// 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;
    }

3-2 實現將兩個非遞減鏈表LA和LB合併排列成一個新的非遞減鏈表LA

// 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

以上即是基於線性表的簡單算法,此係列後面會陸續介紹更多有關數據結構的內容,也會更新一些關於數據結構的算法題目例子,謝謝你們支持!

相關文章
相關標籤/搜索