【Java】 大話數據結構(3) 線性表之靜態鏈表

 

本文根據《大話數據結構》一書,實現了Java版的靜態鏈表java

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

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

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

靜態鏈表的優缺點:ide

靜態鏈表實現程序:測試

package StaticLinkList;
/**
 * 說明:
 * 1.數組第一個元素的cur爲備用鏈表第一個結點下標,
 *   數組最後一個元素的cur爲第一個有數據的元素的下標,至關於頭結點
 *   最後一個有值元素的 cur爲0
 * 2.插入刪除操做時,獲取第i-1個元素的 下標時,應注意i-1=0的狀況
 * 3.註釋中的「位置」指的是在鏈表中的位置,「下標」表明數組中的下標,勿搞混
 * 4.程序關鍵:獲取下標,在數組層面上操做
 * 5.程序中主要寫了插入刪除操做,其他基本操做與以前文章相似
 *  
 * 問題:
 * 1.泛型數組的創建
 * 2.書中P73的if(space[0].cur)和P74的if(j)是屬於判斷什麼?
 * 
 * @author Yongh
 */
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;
	}
		
}

  

測試代碼:this

package StaticLinkList;

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

  

——————————插入1到5,並讀取內容——————————
表長:5
第1個位置爲:小A
第2個位置爲:小B
第3個位置爲:小C
第4個位置爲:小D
第5個位置爲:小E
——————————刪除小B、小E——————————
已刪除:小B
已刪除:小E
當前表長:3
第1個位置爲:小A
第2個位置爲:小C
第3個位置爲:小D
表長:3
StaticLinkListTest
相關文章
相關標籤/搜索