數據結構--線性表

C++中有析構函數,用於銷燬對象時釋放內存,而Java中由於有gc(垃圾回收機制)因此就沒有析構函數,可是java有finalize() 方法,二者的用途相近。java

具體請參考連接:http://blog.csdn.net/jemasw/article/details/8470480node

什麼是線性表?數組

官方定義:線性表是n個數據元素的有限序列函數

順序表和鏈表互爲補充;spa

定義解讀:n個(個數),元素(能夠是複雜元素對象,也能夠是單個數據),有限(有限的),序列(是一個序列集合).net

線性表分爲兩大類:數組和鏈表指針

順序表對象

前驅:指定元素前一個元素blog

後繼:指定元素的後一個元素內存

優勢:能夠經過下標遍歷尋址,因此遍歷和尋址極爲快速。

缺點:插入和刪除元素,由於要移動後面的全部元素,因此較爲緩慢。

 

鏈表

單鏈表:

單鏈表,每一個節點分爲兩部分,分別爲 數據域  指針域

 

initChainList(); 初始化鏈表

void destroyList(); 銷燬鏈表,廢棄

boolean isListEmpty(); 判斷鏈表是否爲空

int listLength(); 獲取鏈表的長度

void clearList(); 清空鏈表的全部元素

Node listInsertHead(Node node); 插入頭節點

Node listInsertTail(Node node); 插入尾節點

Node insertElement(int i, Node node); 指定位置插入節點

Node deleteElement(int i); 刪除指定節點

Node getElement(int i); 獲取指定位置節點

int elementLocate(Node node); 獲取指定節點所在的位置

Node priorElement(Node node); 找到指定節點的前驅

Node nextElement(Node node); 找到指定節點的後繼

void listTraverse(); 遍歷鏈表

循環鏈表

簡單的說,就是首尾相連的單鏈表即尾節點的指針域指向首節點的位置

雙向鏈表

雙向鏈表,每一個節點分爲三部分,分別爲:

前指針域:順向指向下一個節點的位置

數據域:數據節點

後指針域:逆向指向下一個節點的位置

靜態鏈表

 

此處附上順序表的建立代碼:

 

package util;

public class MyList {
    //線性表自己
    private Object myList[];
    //線性表的大小,即最大容量
    private int listSize;
    //線性表的長度,即線性表中的元素個數
    private int myLength;
    
    
    
    public MyList() {
        super();
    }

    /**
     * 初始化線性表 - 順序表
     * @param size
     */
    public MyList(int size) {
        listSize = size;
        //申請線性表內存
        myList = new Object[listSize];
        myLength = 0;
    }
    
    /**
     * 銷燬線性表
     */
    public void DestroyList(){
        myList = null;
    }
    
    /**
     * 清空線性表元素
     */
    public void clearList(){
        myLength = 0;
    }
    
    /**
     * 判斷線性表是否爲空
     * @return
     */
    public boolean isListEmpty(){
        return myLength == 0 ? true : false;
    }
    
    /**
     * 獲取線性表的元素個數
     * @return
     */
    public int listLength(){
        return myLength;
    }
    /**
     * 獲取下標位置的元素
     */
    public Object getElement(int i)
    {
        //須要將i入參進行必定的限制,由於元素存在的位置座標僅限於0到線性表的個數減一(即0~myLength-1),因此若是i小於0或者i大於等於線性表的長度都斷定爲獲取失敗返回null
        if(i < 0 || i >= myLength){
            return null;
        }
        return myList[i];
    }
    
    /**
     * 獲取線性表中元素所在的位置(只獲取第一個遇到的位置)
     * @param element
     * @return
     */
    public int elementLocate(Object element){
        for (int i = 0; i <= myLength; i++){
            if (element.equals(myList[i]))
            {
                return i;
            }
        }
        return -1;
    }
    
    /**
     * 獲取指定元素前驅
     * @param element
     * @return
     */
    public Object priorElement(Object element){
        int i = elementLocate(element);
        if(i == -1){
            //若是i==-1那麼則表示當前線性表中沒有找到元素,因此直接斷定失敗,返回null
            return null;
        }else if(i == 0){
            //若是i==0則該元素自己就是第一個元素,前面不可能再有前驅,因此返回null
            return null;
        }else{
            return myList[i - 1];
        }
    }
    
    /**
     * 獲取指定元素後綴
     * @param element
     * @return
     */
    public Object nextElement(Object element){
        int i = elementLocate(element);
        if(i == -1){
            return null;
        }else if(i == myLength-1){
            return null;
        }else{
            return myList[i + 1];
        }
    }
    
    /**
     * 在指定位置插入元素
     * @param i
     * @param element
     * @return
     */
    public Object insertElement(int i, Object element)
    {
        if(i < 0 || i > myLength)
        {
            return null;
        }
        
        //此處注意要從後向前依次將i後面的元素向後移位
        for (int j = myLength-1; j >= i; j--){
            //依次把前面的元素向後移位
            myList[j + 1] = myList[j];
        }
        
        myList[i] = element;
        
        myLength++;
        
        return element;
    }
    
    /**
     * 刪除指定位置元素
     * @param i
     * @return
     */
    public Object deleteElement(int i){

        if (i < 0 || i >= myLength){
            return null;
        }
        
        Object element = myList[i];
        
        //此處注意要從前向後依次將i後面的元素向後移位,不用單獨執行刪除操做,由於在移位的過程當中已經把i座標的元素給覆蓋了
        for (int j = i + 1; j < myLength; j++){
            //依次把後面的元素向前移位
            myList[j - 1] = myList[j];
        }
        
        myLength--;
        return element;
    }
    
    /**
     * 遍歷線性表中的元素
     */
    public void listTraverse(){
        for (int i = 0; i <= myLength-1; i++){
            System.out.println(myList[i].toString());
        }
    }
}

 

  此處附上鍊表的結構代碼:

package util;

import test.entity.Node;

public class MyChainList {
    
    private Node myChainList;
    
    private int listLength;
    
    /**
     * 初始化鏈表
     */
    public MyChainList() {
        //申請節點內存
        myChainList = new Node();
        
        myChainList.data = null;
        myChainList.next = null;
        
        listLength = 0;  
    }

    /**
     * 銷燬鏈表,廢棄
     */
    public void destroyList(){
        clearList();
        myChainList = null;
    }
    
    /**
     * 判斷鏈表是否爲空
     * @return
     */
    public boolean isListEmpty(){
        return 0 == listLength ? true :false;
    }
    
    /**
     * 獲取鏈表的長度
     * @return
     */
    public int listLength(){
        return listLength;
    }
    
    /**
     * 清空鏈表的全部元素
     */
    public void clearList(){
        Node currentNode = myChainList;
        //初始節點的下一個節點,爲第一個節點,找到第一個節點判斷是否爲空
        while(null != currentNode.next){
            Node temp = currentNode.next;
            //將當前節點刪除
            currentNode = null;
            //查找下一個節點
            currentNode = temp;
        }
        currentNode.data = null;
        currentNode.next = null;
        listLength = 0;
    }
    
    /**
     * 插入頭節點
     * @param node
     * @return
     */
    public Node listInsertHead(Node node){
        //將第一個元素指向的下一個節點,存放備用
        Node temp = myChainList.next;
        
        //從堆內存中申請空間,將數據放入內存
        Node newNode = new Node();
        if(null == newNode){
            return null;
        }
        newNode.data = node.data;
        
        //讓新的節點指向,第一個節點原指向的節點
        newNode.next = temp;
        //將node節點放入第一個節點的後面
        myChainList.next = newNode;
        listLength ++;
        return newNode;
    }
    
    /**
     * 插入尾節點
     * @param node
     * @return
     */
    public Node listInsertTail(Node node){
        Node currentNode = myChainList;
        //重第一個節點開始循環查找下一個節點,知道找到尾節點
        while(null != currentNode.next)
        {
            currentNode = currentNode.next;
        }
      
        //從堆內存中申請空間,將數據放入內存
        Node newNode = new Node();
        if(null == newNode){
            return null;
        }
        newNode.data = node.data;
        newNode.next = null;
        
        //將新節點插入尾節點的後面
        currentNode.next = newNode;
        
        listLength ++;
        return newNode;
    }
    
    /**
     * 指定位置插入節點
     * @param i
     * @param node
     * @return
     */
    public Node insertElement(int i, Node node){
        
        //判斷i是否合法
        if (i < 0 || i > listLength){
            return null;
        }
        
        //遍歷節點找到 i 位置的上一個節點
        Node currentNode = myChainList;
        for (int j = 0; j < i; j++){
            currentNode = currentNode.next;
        }
        
        Node newNode = new Node();
        if (null == newNode){
            return null;
        }
        
        newNode.data = node.data;
        //將原位於i位置的節點放入新節點的後面
        newNode.next = currentNode.next;
        //將新節點,放入i上一個節點的後面
        currentNode.next = newNode;
        
        listLength ++;
        return newNode;
    }
    
    /**
     * 刪除指定節點
     * @param i
     * @return
     */
    public Node deleteElement(int i){
        
        if (i < 0 || i >= listLength){
            return null;
        }
        
        //找到第i個節點,和i的上一個節點
        Node currentNode = myChainList;
        Node currentNodeBefore = null;
        for (int j = 0; j <= i; j++){
            currentNodeBefore = currentNode;
            currentNode = currentNode.next;
        }
        
        //將i位置後面的節點,放在i前面節點的後面
        currentNodeBefore.next = currentNode.next;
        Node temp = currentNode;
        
        currentNode = null;
        listLength --;
        return temp;
    }
    
    /**
     * 獲取指定位置節點
     * @param i
     * @return
     */
    public Node getElement(int i){
        
        //過濾i的合理範圍
        if (i < 0 || i >= listLength){
            return null;
        }
        
        // 找到第i個節點
        Node currentNode = myChainList;
        for (int j = 0; j <= i; j++){
            currentNode = currentNode.next;
        }
        
        return currentNode;
    }
    
    /**
     * 獲取指定節點所在的位置
     * @param node
     * @return
     */
    public int elementLocate(Node node){
        
        //循環查找全部節點
        Node currentNode = myChainList;
        int count = 0;
        while(null != currentNode.next){
            currentNode = currentNode.next;
            //找到鏈表中第一個與指定節點匹配的節點
            if (currentNode.data.equals(node.data)){
                //返回當前循環的次數
                return count;
            }
            //每執行一次表示當前位置沒有匹配的節點,注意不能放在if前面
            count++;
        }
        
        return -1;
    }
    
    /**
     * 找到指定節點的前驅
     * @param node
     * @return
     */
    public Node priorElement(Node node){
        
        //找到 指定節點 和 指定節點的 上一個節點
        Node currentNode = myChainList;
        Node currentNodeBefore = null;
        while(null != currentNode.next){
            currentNodeBefore = currentNode;
            currentNode = currentNode.next;
            
            //匹配到了第一個與指定節點相同的節點
            if (node.data.equals(currentNode.data)){
                //若是找到的對象是線性表中的第一個元素,那麼他就沒有前驅,返回null
                if (currentNodeBefore.equals(myChainList)){
                    return null;
                }
                return currentNodeBefore;
            }
        }
        return null;
    }
    
    /**
     * 找到指定節點的後繼
     * @param node
     * @return
     */
    public Node nextElement(Node node){
        //遍歷線性表,找到指定節點
        Node currentNode = myChainList;
        while(null != currentNode.next){
            currentNode = currentNode.next;
            //若是找到了元素
            if (currentNode.data.equals(node.data)){
                //判斷該元素是否爲線性表中的最後一個元素,最後一個元素沒有後綴,直接返回null
                if (currentNode.next == null){
                    return null;
                }
                return currentNode.next;
            }
        }
        return null;
    }
    
    /**
     * 遍歷鏈表
     */
    public void listTraverse(){
        //遍歷鏈表中的全部元素,依次打印出他們的 數據域
        Node currentNode = myChainList;
        while(null != currentNode.next){
            currentNode = currentNode.next;
            currentNode.printNode();
        }
    }
}
相關文章
相關標籤/搜索