Java實(shí)現(xiàn)線性表的順序和鏈?zhǔn)酱鎯?chǔ)

什么是線性表?

? 線性表(Linear List),是由同類型數(shù)據(jù)元素構(gòu)成有序序列的線性結(jié)構(gòu),表中元素個(gè)數(shù)稱為線性表的長(zhǎng)度;線性表沒有元素時(shí),稱為空表;表的起始位置稱為表頭,表的結(jié)束位置稱為表尾。

抽象數(shù)據(jù)類型描述

? 類型名稱:線性表(List)

? 數(shù)據(jù)對(duì)象集:線性表是n(n>=0)個(gè)元素構(gòu)成的有序序列(a,a2,...,an)

? 操作集:Item 表示元素類型,整數(shù) i 表示位置

  • boolean isEmpty() 線性表是否為空
  • int size() 線性表中的元素個(gè)數(shù)
  • void insert(Item item, int i) 在 i 位置插入元素
  • void delete(int i) 在第i個(gè)位置刪除數(shù)據(jù)(即刪除數(shù)組下標(biāo)為i-1這個(gè)位置)
  • int find(Item item) 查找某個(gè)元素,如果找到,返回下標(biāo);否則返回-1

順序存儲(chǔ)實(shí)現(xiàn)(固定大?。?/h3>

? 創(chuàng)建一個(gè)泛型類List:

public class List<Item>{
    private Item[] data; // 泛型數(shù)組存儲(chǔ)數(shù)據(jù)
    private int last = -1; // last表示最后一個(gè)元素的下標(biāo)
}

? 構(gòu)造函數(shù):

public List(int size){
        data = (Item[]) new Object[size]; // java不允許創(chuàng)建泛型數(shù)組,所以需要用到類型轉(zhuǎn)換
}

插入數(shù)據(jù)

? 在這里,我們插入數(shù)據(jù)的位置范圍是1n+1,即第一個(gè)位置到最后一個(gè)位置+1(這里的n就表示當(dāng)前List中的元素個(gè)數(shù))。所以我們就會(huì)發(fā)現(xiàn)我們?cè)诓迦霐?shù)據(jù)后,這些數(shù)據(jù)都是連續(xù)的。比如:在創(chuàng)建了List之后,數(shù)組中沒有元素,元素個(gè)數(shù)為0,那么此時(shí)插入的范圍就是10+1,只有1這個(gè)位置可以插入,之后再插入第二個(gè)元素,這時(shí)元素的個(gè)數(shù)已經(jīng)變成了1,此時(shí)的范圍是1~1+1,以此類推,存儲(chǔ)在這個(gè)線性表中的數(shù)據(jù)總會(huì)是連續(xù)的。

image

? 當(dāng)我們向線性表中插入數(shù)據(jù)時(shí),首先要看看這個(gè)線性表滿了沒有,如果滿了不能插入,判斷滿的條件就是:last==data.length-1如果最后一個(gè)元素的下標(biāo)等于數(shù)組的最后一個(gè)下標(biāo),說明滿了。

? 然后,要判斷插入的位置是否合法:i < 1 || i > last+2(n+1 >= i >= 1)。

? 之前說過,List中存儲(chǔ)的數(shù)據(jù)是連續(xù)的,所以我們插入時(shí)不能直接插入,需要將元素往后挪出一個(gè)空位才能夠在特定的位置進(jìn)行插入:

// 挪動(dòng)的順序毫無疑問是從最后一個(gè)元素挪,否則你從第i個(gè)元素挪的話就會(huì)覆蓋掉后面的元素
for (int j=last; j>=i-1; j--){
    data[j+1] = data[j];
}
// 插入數(shù)據(jù)
data[i-1] = item;
// last加1
last = last + 1;

刪除元素

? 和插入元素類似,只是挪動(dòng)元素是往前挪動(dòng)元素,填補(bǔ)刪除后留下的空位。直接上代碼:

// 如果List空,不能刪除
if (isEmpty()){
    System.out.println("List為空,不能刪除");
}
// 規(guī)定的刪除位置在1~n+1
if (i < 1 || i > last+2){
    System.out.println("刪除位置非法,無法插入!");
}
// 在刪除之后需要先將數(shù)據(jù)往前挪
for (int j=i-1; j<last; j++){
    data[j] = data[j+1];
}
last = last - 1;

完整代碼:

public class List<Item> {
    // Java不允許創(chuàng)建泛型數(shù)組,所以做強(qiáng)制類型轉(zhuǎn)換
    private Item[] data;
    private int last = -1; // 表示List中最后一個(gè)元素的下標(biāo)

    // 構(gòu)造函數(shù)-創(chuàng)建List時(shí)指定大小
    public List(int size){
        data = (Item[]) new Object[size];
    }

    // List是否為空
    public boolean isEmpty(){
        return last==-1;
    }

    // 返回List的大小
    public int size(){
        return last+1;
    }

    // 在第i個(gè)位置插入數(shù)據(jù)(即插入到數(shù)組下標(biāo)為i-1這個(gè)位置)
    public void insert(Item item, int i){
        // 如果List滿了,不能插入
        if (last==data.length-1){
            System.out.println("數(shù)組滿,無法插入!");
        }
        // 規(guī)定的插入位置在1~n+1之間
        if (i < 1 || i > last+2){
            System.out.println("插入位置非法,無法插入!");
        }
        // 在插入之前需要先將數(shù)據(jù)往后挪
        for (int j=last; j>=i-1; j--){
            data[j+1] = data[j];
        }
        data[i-1] = item;
        last = last + 1;
    }

    // 在第i個(gè)位置刪除數(shù)據(jù)(即刪除數(shù)組下標(biāo)為i-1這個(gè)位置)
    public void delete(int i){
        // 如果List空,不能刪除
        if (isEmpty()){
            System.out.println("List為空,不能刪除");
        }
        // 規(guī)定的刪除位置在1~n+1
        if (i < 1 || i > last+2){
            System.out.println("刪除位置非法,無法插入!");
        }
        // 在刪除之后需要先將數(shù)據(jù)往前挪
        for (int j=i-1; j<last; j++){
            data[j] = data[j+1];
        }
        last = last - 1;
    }

    // 查找某個(gè)元素,如果查找到,返回下標(biāo),否則返回-1
    public int find(Item item){
        for (int i=0; i<last+1; i++){
            if (data[i]==item){
                return i;
            }
        }
        return -1;
    }

    public void printData(){
        for (Item item:data){
            System.out.print(" " + item);
        }
        System.out.println("");
    }

    // 測(cè)試
    public static void main(String[] args) {
        List<Integer> testList = new List(5);
        testList.insert(1,1);
        testList.insert(2,2);
        testList.insert(3,3);
        testList.insert(4,4);
        testList.insert(5,5);
        testList.printData();
        testList.delete(1);
        testList.printData();
        System.out.println(testList.find(3));
    }
}

鏈?zhǔn)酱鎯?chǔ)實(shí)現(xiàn)

? 創(chuàng)建一個(gè)泛型類 LinkedList:

public class LinkedList<Item> {
    private Node head; // 線性表的表頭(鏈表的入口)
    private int N; // 結(jié)點(diǎn)的數(shù)量(線性表中的元素?cái)?shù)量)

    // node結(jié)點(diǎn)類
    private class Node{
        Item item;
        Node next;
        // 構(gòu)造器
        public Node(Item item, Node next) {
            this.item = item;
            this.next = next;
        }
    }
}

? 求線性表的長(zhǎng)度和是否為空:

public int length(){
    return N;
}

public boolean isEmpty(){
    return head==null; // 當(dāng)head為null或N為0
}

? 查找相應(yīng)的位置的結(jié)點(diǎn):

public Node findXth(int X){
    Node temp = head;
    int i = 1;
    // 當(dāng)當(dāng)前結(jié)點(diǎn)不為空且位置小于X時(shí)
    while (temp != null && i < X){
        temp = temp.next;
        i = i+1;
    }
    // 跳出循環(huán)有兩種可能,當(dāng)前結(jié)點(diǎn)為空或i==X
    if (i == X){
        return temp;
    } else{
        return null;
    }
}

插入數(shù)據(jù)

? 因?yàn)槭擎準(zhǔn)酱鎯?chǔ),所以不必關(guān)心空間的問題,只需care插入問題。

? 要向鏈表中插入結(jié)點(diǎn),首先要分插入的位置。如果是插到鏈表的頭,需要做特殊處理:讓插入結(jié)點(diǎn)的next的值變?yōu)閔ead,head的值置為新插入的結(jié)點(diǎn);如果插入到其他位置,只需要先找到插入位置的前一個(gè)結(jié)點(diǎn)p,然后是兩步(順序不能更改):1、設(shè)置插入的結(jié)點(diǎn)的next的值為p的next。2、改變p的next的值為插入的結(jié)點(diǎn)。

public void insert(int i, Item item){
    Node temp, p;
    if (i == 1){
        temp = new Node(item, head);
        head = temp;
        N = N+1;
        return;
    }
    p = findXth(i-1);
    if (p == null){
        System.out.println("參數(shù)i錯(cuò)誤!");
        return;
    } else{
        temp = new Node(item, p.next);
        p.next = temp;
        N = N+1;
        return;
    }
}

刪除數(shù)據(jù)

? 和插入類似,區(qū)分刪除的是頭結(jié)點(diǎn)還是其他位置,刪除頭結(jié)點(diǎn):只需head置為head的next;刪除其他結(jié)點(diǎn):找到前一個(gè)結(jié)點(diǎn)p,使其next置為p.next.next即可,java會(huì)自動(dòng)進(jìn)行垃圾回收。

public void delete(int i){
    Node p;
    if (i == 1){
        if (head == null){
            System.out.println("鏈表為空!");
            return;
        } else{
            head = head.next;
            N = N-1;
            return;
        }
    }
    p = findXth(i-1);
    if (p == null || p.next == null){
        System.out.println("第i個(gè)結(jié)點(diǎn)不存在!");
    } else {
        p.next = p.next.next;
        N = N-1;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容