JAVA——順序表和鏈表

在談順序表之前我們先談一下線性表,顯而易見爲啥叫線性表,就是因爲表中的元素時連續的,而線性表又分爲順序表和鏈表。
這兩者有啥不同呢?

順序表 鏈表
在物理地址上是連續存儲的 物理存儲結構非連續
可以隨機訪問 只能遍歷查找,不支持隨機訪問
在中間位置或者表頭添加元素、刪除元素比較噁心 任意位置添加、刪除元素的時間複雜度都是O(1)
擴容的代價比較大 插入元素只需要開闢一個新的節點

一、順序表

說白了,順序表就是數組,依託於數組進行增刪改查等操作。 順序表又包含:
  1. 靜態順序表:使用定長數組存儲
  2. 動態順序表:使用動態開闢的數組存儲
    想對來說還是動態順序表更好用,更靈活一點,在這裏我實現動態順序表藉助於重新創建一個長度爲原長2倍的新的數組來實現。
import java.io.InputStream;

public class SuquenceTable {
    //先創建一個定長爲100的數組
    int[] arr = new int[100];
    //記錄順序表中真實存儲的元素
    int size = 0;
    //在指定位置增加元素
    public void addElem(int pos,int elem) {
        if (pos > arr.length || pos < 0) {
            return;
        }
        if(size >= arr.length) {
            relloc();
        }
        if (pos == size) {
            arr[pos] = elem;
            size++;
        }else {
            for (int i = size;i > pos;i--) {
                arr[i] = arr[i-1];
            }
            arr[pos] = elem;
            size++;
        }
    }
    //擴容
    private void relloc() {
        int[] newArr = new int[arr.length * 2];
        System.arraycopy(this.arr,0,newArr,0,this.arr.length);
        this.arr = newArr;
    }
    //得到某個位置的元素
    public Integer getPos(int pos) {
        if (pos < 0) {
            System.out.println("該位置沒有元素");
            return null;
        }else {
            return arr[pos];
        }
    }
    //查看是否包含某個元素
    public boolean isContains(int key) {
        return this.search(key) != -1;
    }
    public int search(int key) {
        for (int i = 0; i < this.arr.length; i++) {
            if (key == arr[i]) {
                return i;
            }
        }
        return -1;
    }
    //刪除第一次出現的某個元素
    public void remove(int key) {
        int pos = search(key);
        if (pos == -1) {
            return;
        }
        if (pos == size - 1){
            size--;
            return;
        }
        for (int i = pos;i < size - 1;i++) {
            this.arr[i] = this.arr[i+1];
        }
        size--;
        return;
    }
    //得到順序表大小
    public int getSize(){
        return this.size;
    }
    //清空順序表
    public void clear() {
        int[] newArr = new int[this.arr.length];
        this.arr = newArr;
        size = 0;
    }
}

二、鏈表

我實現一下最簡單的無頭單鏈表好了,沒有爲啥,問就是簡單。
package LinkList;
class LinkedNode{
    int val;
    LinkedNode next;
    public LinkedNode(int val) {
        this.val = val;
    }
}
public class LinkedList {
    LinkedNode head = null;
    //頭插
    public void addFirst(int val) {
        LinkedNode node = new LinkedNode(val);
        if (this.head == null) {
            this.head = node;
            return;
        }
        node.next = head;
        head = node;
        return;
    }
    //尾插
    public void addLast(int val) {
        LinkedNode node = new LinkedNode(val);
        if (this.head == null) {
            head = node;
            return;
        }
        LinkedNode cur = this.head;
        while (cur.next != null) {
            cur = cur.next;
        }
        node.next = cur.next;
        cur.next = node;
        return;
    }
    //刪除第一次出現的某個元素
    public void remove(int val) {
        if (this.head == null) {
            return;
        }
        if (this.head.val == val) {
            this.head = this.head.next;
            return;
        }
        LinkedNode node = this.head;
        LinkedNode cur = null;
        while (node.next != null) {
            cur = node.next;
            if (cur.val == val) {
                break;
            }
            node = node.next;
        }
        if (cur == null) {
            return;
        }
        node.next = cur.next;
    }
    //刪除所有出現的某個元素
    public void removeAll(int val) {
        if (this.head == null) {
            return;
        }
        LinkedNode first = this.head.next;
        LinkedNode slow = head;
        while (first != null ) {
            if(first.val == val) {
                slow.next = first.next;
                first = first.next;
            }else {
                first = first.next;
                slow = slow.next;
            }
        }
        if (this.head.val == val) {
            this.head = this.head.next;
        }
    }
    /*反轉一個鏈表*/
    private void reversrList(LinkedNode head) {
        //鏈表爲空或只有一個元素就返回
        if (head == null || head.next == null) {
            return;
        }
        LinkedNode newHead = null;
        LinkedNode newTail = newHead;
        LinkedNode cur = head;
        while (cur!= null) {
            LinkedNode next = cur.next;
            if (next == null) {
                newHead = cur;
                break;
            }
            cur.next = newTail;
            newTail = cur;
            cur = next;
        }
        head = newHead;
    }
    /*合併兩個鏈表*/
    public LinkedNode mergeList(LinkedNode h1,LinkedNode h2) {
        if (h1 == null) {
            return h2;
        }
        if (h2 == null) {
            return h1;
        }
        LinkedNode newHead = new LinkedNode(0);
        LinkedNode newTail = newHead;
        LinkedNode prve = h1;
        LinkedNode cur = h2;
        while (prve != null && cur != null) {
            if (prve.val > cur.val) {
                newTail.next = new LinkedNode(cur.val);
                cur = cur.next;
            }else {
                newTail.next = new LinkedNode(prve.val);
                prve = prve.next;
            }
            newTail = newTail.next;
        }
        if (cur == null) {
            newTail.next = prve;
        }
        if (prve == null) {
            newTail.next = cur;
        }
        return newHead.next;
        }
    /*按給定值分割鏈表*/
    public LinkedNode partationList(LinkedNode head,int key) {
        if (head == null || head.next == null) {
            return head;
        }
        LinkedNode bigHead = new LinkedNode(0);
        LinkedNode bigTail = bigHead;
        LinkedNode smallHead = new LinkedNode(0);
        LinkedNode samllTail = smallHead;
        LinkedNode tmp = head;
        while (tmp != null) {
            if (tmp.val < key) {
                samllTail.next = new LinkedNode(tmp.val);
                samllTail = samllTail.next;
            }else {
                bigTail.next = new LinkedNode(tmp.val);
                bigTail = bigTail.next;
            }
            tmp = tmp.next;
        }
        samllTail.next = bigHead.next;
        return smallHead.next;
    }
    /*刪除一個已排序鏈表的所有重複元素*/
    public LinkedNode deleteDuplication(LinkedNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        LinkedNode newHead = new LinkedNode(0);
        newHead.next = head;
        LinkedNode prve = newHead;
        LinkedNode cur = prve.next;
        while (cur != null) {
            if (cur.val == cur.next.val && cur.next != null) {
                while (cur.next != null && cur.val == cur.next.val) {
                    cur = cur.next;
                }
                prve.next = cur.next;
            }else {
                prve = prve.next;
            }
            cur = cur.next;
        }
        return newHead.next;
    }
    public boolean isPalindrome(LinkedNode head) {
        if (head == null || head.next == null) {
            return true;
        }
        int steps = getSize(head)/2;
        LinkedNode newHead = head;
        for (int i = 0;i < steps;i++) {
            newHead = newHead.next;
        }
        LinkedNode cur = newHead;
        LinkedNode prve = null;
        while (cur != null) {
            LinkedNode next = cur.next;
            if (next == null) {
                newHead = cur;
                break;
            }
            cur.next = prve;
            prve = cur;
            cur = next;
        }
        while (newHead != null) {
            if (newHead.val != head.val) {
                return false;
            }
            newHead = newHead.next;
            head = head.next;
        }
        return true;
    }
    public int getSize(LinkedNode head) {
        LinkedNode node = head;
        int size = 0;
        while (node != null) {
            node = node.next;
            size++;
        }
        return size;
    }
}

鏈表還有好多好多,不過我都還不是很會(- _ -),就不列舉了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章