1. 程式人生 > >資料結構——線性表——順序表

資料結構——線性表——順序表

1. 線性表

  線性表是最常用且最簡單的資料結構。簡而言之,一個線性表是n個數據元素的有限序列。至於每一個元素的具體含義,在不同的情況下各不相同,它可以是一個數字或一個符號,也可以是一頁書,甚至是更復雜的資訊。

2. 線性表的特點

  • 存在唯一一個被稱作“第一個”的資料元素;

  • 存在唯一的一個被稱作“最後一個”的資料元素;

  • 除第一個元素以外,集合中的每一個元素均只有一個前驅;

  • 除最後一個以外,集合中的每一個元素均只有一個後繼。

3. 線性表的原始碼

AbstractLineMethod.java

package com.mycompany;

import util.ObjectHolder;

/**
 * Created by HP on 2017/9/6.
 */
public interface AbstractLineMethod { /** * 初始化線性表 * @param size */ void initList(int size); /** * 銷燬線性表 */ void destroyList(); /** * 清空線性表 */ void clearList(); /** * 線性表判空 * @return */ boolean listEmpty(); /** * 獲取線性表的長度 * @return
*/
int listLength(); /** * 獲取指定位置處的元素 * @param i * @param ele * @return */ public boolean getElem(int i, ObjectHolder ele); /** * 獲取該元素線上性表中第一次出現的位置 * @param ele * @return */ public int locateElem(ObjectHolder ele); /** * 獲取指定元素的前驅 * @param
currentElem * @param preElem * @return */
public boolean priorElem(ObjectHolder currentElem,ObjectHolder preElem); /** * 獲取指定元素的後繼 * @param currentElem * @param nextElem * @return */ public boolean nextElem(ObjectHolder currentElem,ObjectHolder nextElem); /** * 線上性表的指定位置處插入元素 * @param i * @param ele * @return */ public boolean listInsert(int i,Object ele); /** * 刪除線性表指定位置處的元素 * @param i * @param ele * @return */ public boolean listDelete(int i,ObjectHolder ele); /** * 迴圈遍歷線性表 */ public void listTraverse(); }

LineMethod.java

package com.mycompany;

import util.ObjectHolder;

/**
 * Created by HP on 2017/9/6.
 */
public class LineMethod implements AbstractLineMethod{

    private int m_size = 0;
    private Object[] m_pList = null;
    private int m_iLength = 0;

    /**
     * 初始化線性表
     * @param size
     */
    public void initList(int size){
        this.m_size = size;
        this.m_pList = new Object[size];
        this.m_iLength = 0;
    }

    /**
     * 銷燬線性表
     */
    public void destroyList(){
        this.m_pList = null;
        this.m_size = 0;
        this.m_iLength = 0;
    }

    /**
     * 將線性表指標歸零
     */
    public void clearList(){
        this.m_iLength = 0;
    }

    /**
     * 判空操作
     * 如果線性表為空,則返回true否則返回false
     * @return
     */
    public boolean listEmpty(){
        if(this.m_iLength == 0){
            return true;
        }
        return false;
    }

    /**
     * 返回線性表的長度
     * @return
     */
    public int listLength(){
        return m_iLength;
    }

    /**
     * 獲取指定位置處的元素
     * @param i
     * @param ele
     * @return
     */
    public boolean getElem(int i, ObjectHolder ele){
        if(i < 0 || i >= m_size){
            return false;
        }
        ele.object = this.m_pList[i];
        return true;
    }

    /**
     * 尋找第一個滿足ele的資料元素的位序
     * @param ele
     * @return
     */
    public int locateElem(ObjectHolder ele){
        for(int i = 0;i < this.m_iLength; i++){
            if(this.m_pList[i] == ele.object){
                return i;
            }
        }
        return -1;
    }

    /**
     * 獲取指定元素的前驅,如果存在,則返回true,不存在則返回false
     * @param currentElem
     * @param preElem
     * @return
     */
    public boolean priorElem(ObjectHolder currentElem,ObjectHolder preElem){
        //如果查詢元素不位於線性表,則返回false
        int temp = locateElem(currentElem);
        if(temp == -1){
            return false;
        }
        //第一個元素沒有前驅,所以說應該加以排除
        if(temp == 0){
            return false;
        }
        preElem.object = this.m_pList[temp - 1];
        return true;
    }

    /**
     * 獲取指定元素的後繼,如果存在則返回true,如果不存在則返回false
     * @param currentElem
     * @param nextElem
     * @return
     */
    public boolean nextElem(ObjectHolder currentElem,ObjectHolder nextElem){
        //如果所查詢元素不是位於線性表中,則返回false
        int temp = locateElem(currentElem);
        if(temp == -1){
            return false;
        }
        //最後一個元素沒有後繼,應該加以排除
        if(temp == this.m_iLength -1){
            return false;
        }
        nextElem.object = this.m_pList[temp + 1];
        return true;
    }

    /**
     * 在指定位置處插入指定元素,如果插入成功則返回true,失敗則返回false
     * @param i
     * @param ele
     * @return
     */
    public boolean listInsert(int i,Object ele){
        if(i < 0 || i > this.m_iLength){
            return false;
        }
        for (int k = this.m_iLength - 1;k >= i;k --){
            this.m_pList[k + 1] = this.m_pList[k];
        }
        this.m_pList[i] = ele;
        this.m_iLength ++;
        return true;
    }

    /**
     * 線上性表中刪除指定的元素,如果刪除成功,則返回true,如果刪除失敗則返回false
     * @param i
     * @param ele
     * @return
     */
    public boolean listDelete(int i,ObjectHolder ele){
        if(i < 0 || i >= this.m_iLength){
            return false;
        }
        ele.object = this.m_pList[i];
        for(int k = i +1;k < this.m_iLength;k ++){
            this.m_pList[k - 1] = this.m_pList[k];
        }
        this.m_iLength --;
        return true;
    }

    /**
     * 迴圈遍歷線性表中的元素
     */
    public void listTraverse(){
        for(int i = 0;i < this.m_iLength;i ++){
            System.out.println(this.m_pList[i]);
        }
    }


}

Union.java

package util;

/**
 * Created by HP on 2017/9/6.
 */
public class ObjectHolder {

    public Object object;

}

  線性表是一個相當靈活的資料結構,它的長度可以根據需要增長或縮短,即對線性表的資料元素不僅可以進行訪問,還可以進行插入和刪除等操作。

  下面是對於上面線性表所執行的CRUD操作

TestLineMethod.java

package com.mycompany;

import org.apache.log4j.Logger;
import org.junit.Assert;
import org.junit.Test;
import util.ObjectHolder;

/**
 * Created by HP on 2017/9/7.
 */
public class TestLineMethod {

    private static final Logger log = Logger.getLogger(TestLineMethod.class);

    public AbstractLineMethod createList(){
        Object e1 = 3;
        Object e2 = 5;
        Object e3 = 7;
        Object e4 = 2;
        Object e5 = 9;
        Object e6 = 1;
        Object e7 = 8;
        AbstractLineMethod abstractLineMethod = new LineMethod();
        abstractLineMethod.initList(10);
        abstractLineMethod.listInsert(0,e1);
        abstractLineMethod.listInsert(1,e2);
        abstractLineMethod.listInsert(2,e3);
        abstractLineMethod.listInsert(3,e4);
        abstractLineMethod.listInsert(4,e5);
        abstractLineMethod.listInsert(5,e6);
        abstractLineMethod.listInsert(6,e7);
        return abstractLineMethod;
    }

    /**
     * 測試增加資料
     */
    @Test
    public void testInsert(){
        AbstractLineMethod abstractLineMethod = createList();
        abstractLineMethod.listTraverse();
        //輸出結果:3,5,7,2,9,1,8
        Assert.assertEquals(7,abstractLineMethod.listLength());
    }

    /**
     * 測試刪除資料
     */
    @Test
    public void testDelete(){
        ObjectHolder ele = new ObjectHolder();
        AbstractLineMethod abstractLineMethod = createList();
        abstractLineMethod.listDelete(1,ele);
        abstractLineMethod.listTraverse();
        //輸出結果:3,7,2,9,1,8
        Assert.assertEquals(6,abstractLineMethod.listLength());
    }

    /**
     * 測試修改
     * 修改操作實際上我們可以看做是兩個基本操作的合成操作
     * 也就是說修改操作我們可以看成是刪除操作+新增操作,所以說我們在這裡可以這樣做
     */
    @Test
    public void testUpdate(){
        ObjectHolder ele = new ObjectHolder();
        AbstractLineMethod abstractLineMethod = createList();
        //先執行刪除操作
        abstractLineMethod.listDelete(1,ele);
        //再執行插入操作
        abstractLineMethod.listInsert(1,9);
        abstractLineMethod.listTraverse();
        //輸出結果:3,9,7,2,9,1,8
        Assert.assertEquals(7,abstractLineMethod.listLength());
    }

    /**
     * 查詢資料
     */
    @Test
    public void testSearch(){
        //被查詢元素
        ObjectHolder ele = new ObjectHolder();
        ele.object = 7;
        AbstractLineMethod abstractLineMethod = createList();
        abstractLineMethod.listTraverse();
        //輸出結果3,5,7,2,9,1,8
        int i = abstractLineMethod.locateElem(ele);
        Assert.assertEquals(2,i);
        log.info("該元素第一次出現的位置為:" + i);
    }

    /**
     * 獲取前驅
     */
    @Test
    public void testPriorElem(){
        ObjectHolder ele = new ObjectHolder();
        ObjectHolder current = new ObjectHolder();
        current.object = 9;
        AbstractLineMethod abstractLineMethod = createList();
        abstractLineMethod.listTraverse();
        //輸出結果3,5,7,2,9,1,8
        Assert.assertEquals(true,abstractLineMethod.priorElem(current,ele));
        Assert.assertEquals(2,ele.object);
        log.info("前驅元素為:" + ele.object);
    }

    /**
     * 獲取後繼元素
     */
    @Test
    public void testNextElem(){
        ObjectHolder ele = new ObjectHolder();
        ObjectHolder current = new ObjectHolder();
        current.object = 9;
        AbstractLineMethod abstractLineMethod = createList();
        abstractLineMethod.listTraverse();
        //輸出結果3,5,7,2,9,1,8
        Assert.assertEquals(true,abstractLineMethod.nextElem(current,ele));
        Assert.assertEquals(1,ele.object);
        log.info("後繼元素為:" + ele.object);
    }

    /**
     * 獲取指定位置處的元素
     */
    @Test
    public void testGetElem(){
        ObjectHolder ele = new ObjectHolder();
        AbstractLineMethod abstractLineMethod = createList();
        abstractLineMethod.listTraverse();
        //輸出結果3,5,7,2,9,1,8
        Assert.assertEquals(true,abstractLineMethod.getElem(2,ele));
        Assert.assertEquals(7,ele.object);
        log.info("在索引值為2出的元素值為:" + ele.object);
    }

}

4. 專案原始碼

  文章中所引用的程式碼已經作為開源專案“linear-table”被我存放到了CSDN.NET上供大家下載,但是我這裡並不貼出該專案在CSDN.NET中的原始碼,因為CSDN已經決定將CSDN.NET遷移到碼雲上,所以說我這裡就直接上存放到碼雲上的開源專案“linear-table”。

CSDN.NET遷移到碼雲上的公告

linear-table開源專案下載地址