線性表--順序存儲(chǔ)結(jié)構(gòu)

一、線性表的順序存儲(chǔ)結(jié)構(gòu)

線性表有兩種物理存儲(chǔ)結(jié)構(gòu):順序存儲(chǔ)結(jié)構(gòu)和鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)。

順序存儲(chǔ)結(jié)構(gòu)

①定義:
用一段地址連續(xù)的存儲(chǔ)單元依次存儲(chǔ)線性表的數(shù)據(jù)元素。

②線性表(a1,a2,…,an)的順序存儲(chǔ)如下:

線性表的順序存儲(chǔ)結(jié)構(gòu).jpg

物理上的存儲(chǔ)方式事實(shí)上就是在內(nèi)存中找個(gè)初始地址,然后通過(guò)占位的形式,把一定的內(nèi)存空間給占了,然后把相同數(shù)據(jù)類型的數(shù)據(jù)元素依次放在這塊空地中。

③線性表順序存儲(chǔ)結(jié)構(gòu)的結(jié)構(gòu)代碼:

#define MAXSIZE 20    
typedef int ElemType;
typedef struct
{
    ElemType data[MAXSIZE];
    int length;    // 線性表當(dāng)前長(zhǎng)度
} SqList;

④順序存儲(chǔ)結(jié)構(gòu)封裝需要三個(gè)屬性:

  • 存儲(chǔ)空間的起始位置,數(shù)組data,它的存儲(chǔ)位置就是線性表存儲(chǔ)空間的存儲(chǔ)位置。
  • 線性表的最大存儲(chǔ)容量:數(shù)組的長(zhǎng)度MaxSize。
  • 線性表的當(dāng)前長(zhǎng)度:length。

注意:數(shù)組的長(zhǎng)度與線性表的當(dāng)前長(zhǎng)度需要區(qū)分一下:數(shù)組的長(zhǎng)度是存放線性表的存儲(chǔ)空間的總長(zhǎng)度,一般初始化后不變。而線性表的當(dāng)前長(zhǎng)度是線性表中元素的個(gè)數(shù),是會(huì)變化的。

二、地址計(jì)算方法

假設(shè)ElemType占用的是c個(gè)存儲(chǔ)單元(字節(jié)),那么線性表中第i+1個(gè)數(shù)據(jù)元素和第i個(gè)數(shù)據(jù)元素的存儲(chǔ)位置的關(guān)系是(LOC表示獲得存儲(chǔ)位置的函數(shù)):LOC(ai+1) = LOC(ai) + c

所以對(duì)于第i個(gè)數(shù)據(jù)元素ai的存儲(chǔ)位置可以由a1推算得出:LOC(ai) = LOC(a1) + (i-1)*c

地址計(jì)算方法.jpg

通過(guò)這個(gè)公式,我們可以隨時(shí)計(jì)算出線性表中任意位置的地址,不管它是第一個(gè)還是最后一個(gè),都是相同的時(shí)間。那么它的存儲(chǔ)時(shí)間性能就為O(1),我們通常稱為隨機(jī)存儲(chǔ)結(jié)構(gòu)。

注意:線性表是從1開始計(jì)算的

三、線性表的操作

1.獲得元素

實(shí)現(xiàn)GetElem的具體操作,即將線性表L中的第i個(gè)位置元素值返回。就程序而言非常簡(jiǎn)單了,我們只需要把數(shù)組第i-1下標(biāo)的值返回即可。

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status;

// Status 是函數(shù)的類型,其值是函數(shù)結(jié)果狀態(tài)代碼,如OK等。
// 初始條件:順序線性表L已存在,1 <= i <= ListLength(L)
// 操作結(jié)果:用e返回L中第i個(gè)數(shù)據(jù)元素的值。

Status GetElem(SqList L, int i, ElemType *e)
{
    if( L.length==0 || i<1 || i>L.length )
    {
        return ERROR;
    }
    *e = L.data[i-1];

    return OK;
}

注:這里返回值類型Status是一個(gè)整型,約定返回1代表OK,返回0代表ERROR。

2.插入操作

線性表的順序存儲(chǔ)結(jié)構(gòu)具有隨機(jī)存儲(chǔ)結(jié)構(gòu)的特點(diǎn),時(shí)間復(fù)雜度為O(1)。

實(shí)現(xiàn)ListInsert(*L, i, e),即在線性表L中的第i個(gè)位置插入新元素e。

插入算法的思路:

  • 如果插入位置不合理,拋出異常;
  • 如果線性表長(zhǎng)度大于等于數(shù)組長(zhǎng)度,則拋出異?;騽?dòng)態(tài)增加數(shù)組容量;
  • 從最后一個(gè)元素開始向前遍歷到第i個(gè)位置,分別將它們都向后移動(dòng)一個(gè)位置;
  • 將要插入元素填入位置i處;
  • 線性表長(zhǎng)+1。

代碼:

/* 初始條件:順序線性表L已存在,1<=i<=ListLength(L)。 */
/* 操作結(jié)果:在L中第i個(gè)位置之前插入新的數(shù)據(jù)元素e,L長(zhǎng)度+1。*/

Status ListInsert(SqList *L, int i, ElemType e)
{
    int k;

    if( L->length == MAXSIZE )  // 順序線性表已經(jīng)滿了
    {
        return ERROR;
    }
    if( i<1 || i>L->length+1)   // 當(dāng)i不在范圍內(nèi)時(shí)
    {
        return ERROR;
    }
    if( i <= L->length )   // 若插入數(shù)據(jù)位置不在表尾
    {
        /* 將要插入位置后數(shù)據(jù)元素向后移動(dòng)一位 */
        for( k=L->length-1; k >= i-1; k-- )
        {
            L->data[k+1] = L->data[k];
        }
    }

    L->data[i-1] = e;  // 將新元素插入
    L->length++;

    return OK;
}

3.刪除操作

算法的思路:

  1. 如果刪除位置不合理,拋出異常;
  2. 取出刪除元素;
  3. 從刪除元素位置開始遍歷到最后一個(gè)元素位置,分別將它們都向前移動(dòng)一個(gè)位置;
  4. 表長(zhǎng)-1。

實(shí)現(xiàn)代碼:

/* 初始條件:順序線性表L已存在,1<=i<=ListLength(L) */
/* 操作結(jié)果:刪除L的第i個(gè)數(shù)據(jù)元素,并用e返回其值,L的長(zhǎng)度-1 */
Status ListDelete(SqList *L, int i, ElemType *e)
{
    int k;

    if( L->length == 0 )
    {
        return ERROR;
    }
    if( i<1 || i>L->length )
    {
        return ERROR;
    }

    *e = L->data[i-1];

    if( i < L->length )
    {
        for( k=i; k < L->length; k++ )
        {
            L->data[k-1] = L->data[k];
        }
    }

    L->length--;

    return OK;
}

插入和刪除的時(shí)間復(fù)雜度:

  • 最好的情況:插入和刪除操作剛好要求在最后一個(gè)位置操作,因?yàn)椴恍枰苿?dòng)任何元素,所以此時(shí)的時(shí)間復(fù)雜度為O(1)。
  • 最壞的情況:如果要插入和刪除的位置是第一個(gè)元素,那就意味著要移動(dòng)所有的元素向后或者向前,所以這個(gè)時(shí)間復(fù)雜度為O(n)。
  • 平均情況,取中間值O((n-1)/2)。平均情況復(fù)雜度簡(jiǎn)化后還是O(n)。

五、線性表順序存儲(chǔ)結(jié)構(gòu)的優(yōu)缺點(diǎn)

線性表的順序存儲(chǔ)結(jié)構(gòu),在存、讀數(shù)據(jù)時(shí),不管是哪個(gè)位置,時(shí)間復(fù)雜度都是O(1)。而在插入或刪除時(shí),時(shí)間復(fù)雜度都是O(n)。
這就說(shuō)明,它比較適合元素個(gè)數(shù)比較穩(wěn)定,不經(jīng)常插入和刪除元素,而更多的操作是存取數(shù)據(jù)的應(yīng)用。

優(yōu)點(diǎn):

  • 無(wú)須為表示表中元素之間的邏輯關(guān)系而增加額外的存儲(chǔ)空間。
  • 可以快速地存取表中任意位置的元素。

缺點(diǎn):

  • 插入和刪除操作需要移動(dòng)大量元素。
  • 當(dāng)線性表長(zhǎng)度變化較大時(shí),難以確定存儲(chǔ)空間的容量。
  • 容易造成存儲(chǔ)空間的“碎片”
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 數(shù)據(jù)結(jié)構(gòu)與算法-目錄 1、線性表的定義:有零個(gè)或多個(gè)數(shù)據(jù)元素組成的有序數(shù)列。 線性表是一種常用的數(shù)據(jù)結(jié)構(gòu)。在實(shí)際應(yīng)...
    香沙小熊閱讀 2,805評(píng)論 0 6
  • 1.線性表的定義 線性表:零個(gè)或多個(gè)數(shù)據(jù)元素的有限序列序列:也就是說(shuō)元素之間是有順序的,若元素存在多個(gè),則第一個(gè)元...
    e40c669177be閱讀 2,199評(píng)論 6 15
  • 3.2 線性表的定義 線性表,從名字上你就能感覺(jué)到,是具有像線一樣的性質(zhì)的表。 零個(gè)或多個(gè)數(shù)據(jù)元素的有限序列。 這...
    努力生活的西魚閱讀 1,052評(píng)論 0 1
  • 相機(jī)佳能750D 參數(shù)不知道為什么iPad上看不到 后期snapeed 大三遙感課實(shí)習(xí) 老師帶我們?nèi)コ缰菰ü沛?zhèn)做...
    魚魚等雨閱讀 264評(píng)論 0 0
  • 怎么樣喝紅酒: 倒出少量的葡萄酒,約四分之一杯。喝葡萄酒最好用專用的葡萄酒杯,握的時(shí)候不要將手掌貼著葡萄酒杯,否則...
    巴黎成哥閱讀 192評(píng)論 0 0

友情鏈接更多精彩內(nèi)容