java与数据结构(2)---java实现静态链表

结点类

 1 //结点类
 2 class Node<T> {
 3     private T data;
 4     private int cursor;
 5 
 6     Node(T data, int cursor) {
 7         this.data = data;
 8         this.cursor = cursor;
 9     }
10 
11     public void setData(T data) {
12         this.data = data;
13     }
14 
15     public void setCursor(int cursor) {
16         this.cursor = cursor;
17     }
18 
19     public T getData() {
20         return this.data;
21     }
22 
23     public int getCursor() {
24         return this.cursor;
25     }
26 
27     public String toString() {
28         StringBuffer sb = new StringBuffer();
29         sb.append(getData());
30         sb.append(" ");
31         sb.append(getCursor()+" ");
32         return sb.toString();
33     }
34 }
View Code

链表接口

//静态链表接口
interface StaticLinkListable<T> {

    
    int Length();//静态链表长度

    int getBackupListFirstIndex();//获取当前备用链表的首结点地址

    T increaseSpaceToBackupList(int k);//将空闲空间回收至备用链表    

    boolean insert(T element);//尾插

    boolean insert(int i, T element);//在第i个位置插入元素element

    T remove(int i);//删除表中第i个位置的元素

    
    void removeAll();//删除表中所有元素
}
View Code

静态链表实现类

//实现了静态链表接口的结点链表
class NodeList<T> implements StaticLinkListable<T> {
    private Node[] node=null;//泛型数组
    private static final int maxSize = 15;

    //创建一张长度为1000的备用链表
    NodeList() {
        this(maxSize);
    }

    //创建一张长度为maxSize的备用链表
    NodeList(int maxSize) {
        node = new Node[maxSize];//泛型数组如何创建?
       //0-998中的cursor依次存放1,2,3,4...999;下标0元素的cursor为1;下标999元素的cursor为0
        for(int i = 0; i < maxSize-1; i++) {
            node[i] = new Node<T>(null,i+1);
           //System.out.println(i+" "+node[i]);
        }
        node[maxSize-1] = new Node<T>(null,0);
        //System.out.println(maxSize-1+" "+node[maxSize-1]);
    }

    
   //获取静态链表中已经被使用了的数组空间
    public int Length() {
        int j = node[maxSize-1].getCursor();
        int length = 0;
        while (j != 0) {
            j = node[j].getCursor();
            length++;
        }
        return length;
    }

   //向备用链表申请一个数组单元,给插入操作使用;若备用链表非空,则返回备用首结点的下标,否则返回0
    public int applySpaceFromBackupList() {
        int i = getBackupListFirstIndex();//当前数组第一个元素的cursor存的值,就是要返回的备用首结点的下标
        if(i != 0 ) {
            node[0].setCursor(i+1);//由于要拿出备用链表的一个单元使用,那么将该单元的下个单元设为备用首结点
        }
        return i;
    }

    
    //获取备用链表首结点所处的单元下标
    public int getBackupListFirstIndex() {
        return node[0].getCursor();
    }

    //尾插
    public boolean insert(T element) {
        int i = Length();
        return insert(i,element);
    }

    //在表中第i个位置插入数据元素T e
    public boolean insert(int i, T element) {
        if(i >= maxSize-1) {
            return false;
        }
        int L = Length();
        if(i >= L)
            i = L+1;
        if(i < 1) 
            i = 1;
        int k = maxSize-1;//999
        //向备用链表申请空间,以存放要添加的数据元素结点
        int m = applySpaceFromBackupList();
        if(m > 0) {
            //找到数组第i个元素的前一个元素的位置
            for(int j = 1; j < i; j++) {
                k = node[k].getCursor();
            }
            //创建一个新的结点,数据是element,cursor指向第i个元素
            //将新生成的结点放入链表的最后一个单元,即备用链表的上一个单元
            node[m] = new Node<T>(element,node[k].getCursor());    
            //使当前数组第i个元素前面元素的cursor指向链表尾结点
            node[k].setCursor(m);
        }
        return true;        
    }

    //删除表中第i个位置的数据元素
    public T remove(int i) {
        if(i > maxSize - 1) 
            return null;
        if(i < 1)
            i = 1;
        int l = Length();
        if(i > l) 
            i = l;
        int k = maxSize-1;
        //找出第i个位置的前一个数据元素位置
        for(int j = 1; j < i; j++)
             k = node[k].getCursor();
        int m = 0;
        //取出前一个数据元素的cursor,也就是i
        m = node[k].getCursor();
        //将前一个数据元素的cursor设置为当前位置上的cursor,即让当前元素的上一个元素的cursor指向当前元素的下一个元素
        node[k].setCursor(node[m].getCursor());
        //将删除的元素空间回收至备用链表,并将删除位置作为添加元素的优先存储空间
        return increaseSpaceToBackupList(m);
    }

    //删除表中所有的元素
    public void removeAll() {
        int firIndex = node[0].getCursor();
        while(node[0].getCursor() != 1) {
            remove(Length());
        }
    }

    //把下标为k的空闲结点回收到备用链表,即将k作为备用链表首结点位置,数组第一个元素中的cursor指向第k个单元
    public T increaseSpaceToBackupList(int k) {
        T temp = (T)node[k].getData();
        int m = node[0].getCursor();
        node[k].setCursor(m);
        node[0].setCursor(k);
        return temp;
    }

    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("[ ");
        sb.append(node[0]+" ");
        int k = node[maxSize-1].getCursor();
        while(k != 0) {
            sb.append(node[k]);
            k = node[k].getCursor();
        }
        sb.append(node[maxSize-1]+" ");
        sb.append("]");
        return sb.toString();
    }

}
View Code

测试

package bistu;

/*
*@author Nora-Xie 
*@time 2013-10-02 PM 22:02
*/
/*早期的高级编程语言如:Basic、Fortran没有指针,链表结构的实现无法动态实现,于是有人想到用数组实现链表,这就是静态链表。*/
/*由数组描述的链表就是静态链表,其核心是两个数据成员、一个概念和首尾特殊元素三个部分。*/
/*两个数据成员:实际有用的数据data+存储数据的数组单元下标值cursor;*/
/*一个概念:备用链表是静态链表中,删除元素和未被使用到的数组元素;*/
/*首尾特殊元素:数组的第一个元素不存放数据信息,其cursor中存放备用链表第一个结点的下标值;最后一个元素cursor保存着第一个数据值的下标
*/

public class TestStaticLinkList {
    public static void main(String[] args) {
        StaticLinkListable<String> list = new NodeList<String>();
        list.insert("甲");
        list.insert("乙");
        list.insert("丙");
        list.insert("丁");
        list.insert("戊");
        list.insert("己");
        list.insert("庚");
        list.insert("辛");
        list.insert("壬");
        list.insert("奎");
        System.out.println(list);
        list.remove(12);
        System.out.println(list);
        list.removeAll();
        System.out.println(list);
    }
}
View Code
原文地址:https://www.cnblogs.com/nora-xie/p/3350468.html