線性表之靜態鏈表(Java)

用數組描述的鏈表,稱爲靜態鏈表

數組元素由兩個數據域datacur組成:data存放數據元素;cur相當於單鏈表中的next指針,稱爲遊標。

某一靜態鏈表結構如圖所示(遊標存放內容可參考程序中的說明1):

靜態鏈表的優缺點:

靜態鏈表實現程序:

/**
 * 說明:
 * 1.數組第一個元素的cur爲備用鏈表第一個結點下標,
 *   數組最後一個元素的cur爲第一個有數據的元素的下標,相當於頭結點
 *   最後一個有值元素的 cur爲0
 * 2.插入刪除操作時,獲取第i-1個元素的 下標時,應注意i-1=0的情況
 * 3.註釋中的“位置”指的是在鏈表中的位置,“下標”代表數組中的下標,勿搞混
 * 4.程序關鍵:獲取下標,在數組層面上操作
 * 5.程序中主要寫了插入刪除操作,其餘基本操作與之前文章類似
 * 
 * 問題:
 * 1.泛型數組的建立
 * 2.書中P73的if(space[0].cur)和P74的if(j)是屬於判斷什麼?
 *
 */
public class StaticLinkList<E> {
    private SNode<E>[] nodes;
    private int maxSize;
     
    public StaticLinkList(){
        this(1000);
    }
    public StaticLinkList(int maxSize){
        this.maxSize=maxSize;
        nodes=new SNode[this.maxSize];//泛型的數組建立似乎有些問題
        for(int i=0;i<this.maxSize-1;i++) {
            nodes[i]=new SNode<E>(null, i+1);
        }
        nodes[maxSize-1]=new SNode<E>(null, 0);
    }
     
    class SNode<E> {
        E data;
        int cur;
        public SNode(E data,int cur){
            this.data=data;
            this.cur=cur;
        }
    }
     
    /**
     * 獲取第i個元素的下標
     */
    public int getIndex(int i){
        if(i<1||i>this.getLength())
            throw new RuntimeException("查找位置錯誤!");
        int k=nodes[maxSize-1].cur;
        for (int j=1;j<i;j++)
            k=nodes[k].cur;
        return k;
    }
     
    /**
     * 獲取第i個元素
     */
    public SNode<E> getElement(int i){
        return nodes[getIndex(i)];
    }
     
 
     
    /**
     * 返回可分配結點下標 
     */
    public int malloc_sll() {
        int i= nodes[0].cur;       
        nodes[0].cur=nodes[i].cur;//第i個分量要拿來用了,所以指向下一個分量
        //注意,不是nodes[0].cur=nodes[0].cur+1,下一個分量不一定就是下標加一;         
        return i;
    }
     
    /**
     * 插入操作,i代表第i個位置,而不是下標
     * 注意插入到第一個位置的特殊性
     */
    public void listInsert(int i,E e) {
        if(i<1||i>this.getLength()+1)
            throw new RuntimeException("插入位置錯誤!");
        if(getLength()==maxSize-2)
            throw new RuntimeException("表已滿,無法插入!");
        int j=this.malloc_sll();
        nodes[j].data=e;
        int p; ////第i-1個元素的下標
        if(i==1) {
            p=maxSize-1;
        }else {
            p=getIndex(i-1);
        }
        nodes[j].cur=nodes[p].cur;
        nodes[p].cur=j;
    }
     
    /**
     * 刪除第i個位置的結點
     */
    public SNode<E> listDelete(int i) {
        if(i<1||i>getLength())
            throw new RuntimeException("刪除位置錯誤!");
        int m= getIndex(i);
        int p; //第i-1個元素的下標
        if(i==1) {
            p=maxSize-1;
        }else {
            p=getIndex(i-1);
        }
        nodes[p].cur=nodes[m].cur;
        free_sll(m);   
        return nodes[m];
    }
     
    /**
     * 將下標爲i元素回收到備用鏈表中
     */
    public void free_sll(int i) {
        nodes[i].cur=nodes[0].cur;
        nodes[0].cur=i;
    }
     
     
    /**
     * 返回靜態鏈表的長度
     */
    public int getLength() {
        int length=0;
        int i=nodes[maxSize-1].cur;
        while(i!=0) {
            i=nodes[i].cur;
            length++;
        }
        return length;
    }
         
}
public class StaticLinkListTest {
    public static void main(String[] args) {   
        StaticLinkList<Student> students =new StaticLinkList<Student>();
        System.out.println("——————————插入1到5,並讀取內容——————————");
        Student[] stus= {new Student("小A",11),new Student("小B",12),new Student("小C",13),
                new Student("小D",14),new Student("小E",151)};
        for(int i=1;i<=5;i++)
            students.listInsert(i, stus[i-1]);
        System.out.println("表長:"+students .getLength());
        Student stu;
        for(int i=1;i<=5;i++) {
            stu=students .getElement(i).data;
            System.out.println("第"+i+"個位置爲:"+stu.name);
        }
        System.out.println("——————————刪除小B、小E——————————");
        stu=students .listDelete(2).data;
        System.out.println("已刪除:"+stu.name);
        stu=students .listDelete(4).data;
        System.out.println("已刪除:"+stu.name);
        System.out.println("當前表長:"+students .getLength());
        for(int i=1;i<=students .getLength();i++) {
            stu=students .getElement(i).data;
            System.out.println("第"+i+"個位置爲:"+stu.name);
        }
        System.out.println("表長:"+students.getLength());     
    }
}
  
class Student{
    public Student(String name, int age) {
        this.name=name;
        this.age=age;
    }
    String name;
    int age;
}

 

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