順序存儲結(jié)構(gòu):
用一段地址連續(xù)的存儲單元依次存儲線性表的數(shù)據(jù)元素,如數(shù)組。物理上的存儲方式事實上就是在內(nèi)存中找個初始地址,然后通過占位的形式,把一定的內(nèi)存空間給占了,然后把相同數(shù)據(jù)類型的數(shù)據(jù)元素依次放在這塊空地中。
1. 線性表順序存儲的結(jié)構(gòu)代碼:
#define MAXSIZE 100 //線性表最大容量
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;
typedef struct{
ElemType data[MAXSIZE];
int length;//線性表的當(dāng)前長度
}SqList;
順序存儲結(jié)構(gòu)封裝需要三個屬性:
存儲空間的起始位置,數(shù)組data,它的存儲位置就是線性表存儲空間的存儲位置
線性表的最大存儲容量: 數(shù)組的長度MAXSIZE
線性表的當(dāng)前長度: length
注意:數(shù)組長度是線性表存儲空間的總長度,一般初始化后不變(部分語言可變是動態(tài)擴容,會影響性能,如Swift中空間不夠則當(dāng)前容量乘以2),而線性表的當(dāng)前長度是線性表中元素的個數(shù),是可變的
數(shù)據(jù)元素ai的存儲位置可以由a1推導(dǎo)出為:LOC(ai) = LOC(a1)+(i-1)*c(c為ElemType占用的存儲單元(字節(jié)),LOC為location,位置)
由這個公式,可以得出它的時間復(fù)雜度為O(1),通常將O(1)這種稱為隨機存儲結(jié)構(gòu)
2.獲得元素操作
實現(xiàn)思想:將線性表L中的第i個位置元素值返回,如果過大或過小,或者線性表長度為0,則拋出異常
GetElem操作
/*
Status是函數(shù)的類型,其值是函數(shù)結(jié)果狀態(tài)代碼,如OK等。
初始條件:順序線性表L已存在,1 <= i <= ListLength(L)
操作結(jié)果:用e返回L中第i個元素的值
*/
Status GetElem(SqList L,int i,ElemType *e)//注意這里的i是從1開始為有效,以后都一樣
{
if (L.length == 0 || i < 1 || i > L.length) {
return ERROR;
}
*e = L.data[i-1];
return OK;
}
可以看到,線性表的順序存儲結(jié)構(gòu)GetElem操作的時間復(fù)雜度為O(1)
3. 插入操作
實現(xiàn)思想:
如果插入位置不合理,拋出異常
如果線性表長度大于等于數(shù)組長度,則拋出異?;騽討B(tài)增加數(shù)組容量
從最后一個元素開始向前遍歷到第i個位置,分別將它們都向后移動一個位置
將要插入元素填入位置i處
-
線性表長度+1
ListInsert操作
Status insertElem(SqList L,int i,ElemType e){
/*
線性表長度已經(jīng)達到最大限制,拋出異常
插入位置過小或過大,拋出異常
*/
if (L.length == MAXSIZE || i < 1 || i > L.length+1) {
return ERROR;
}
//從要插入的位置開始到結(jié)束,所有元素往后移動一位
for (int j = L.length; j > i; j--) {
L.data[j] = L.data[j-1];
}
//在i位置插入元素
L.data[i-1] = e;
//線性表長度加1
L.length++;
return OK;
}
按照最壞情況考慮時間復(fù)雜度,插入的時間復(fù)雜度為O(n)
4. 刪除操作
實現(xiàn)思路:
如果刪除位置不合理,拋出異常
取出刪除元素
從刪除元素位置開始遍歷到最后一個元素位置,分別將它們都向前移動一個位置
-
線性表長度減一
ListDelete操作
Status deleteElem(SqList L,int i,ElemType *e){
if (L.length == 0 || i < 1 || i > L.length) {
return ERROR;
}
//取出第i個位置的數(shù)據(jù)返回
*e = L.data[i-1];
//從刪除位置后一位開始,每個元素往前移動一位
for (int j = i; j < L.length; j++) {
L.data[j-1] = L.data[j];
}
//線性表長度減一
L.length--;
return OK;
}
按照最壞情況考慮時間復(fù)雜度,刪除操作的時間復(fù)雜度為O(n)
5.線性表順序存儲結(jié)構(gòu)的優(yōu)缺點:
. 在存、讀數(shù)據(jù)時,不管是哪個位置,時間復(fù)雜度都是O(1)。而在插入或刪除時,時間復(fù)雜度都是O(n)
. 這就說明,它比較適合元素個數(shù)比較穩(wěn)定,不經(jīng)常插入和刪除元素,而更多的操作是存取數(shù)據(jù)的應(yīng)用
優(yōu)點:
. 無需為表示表中元素之間的邏輯關(guān)系而增加額外的存儲空間
. 可以快速地存取表中任意位置的元素
缺點:
. 插入和刪除操作需要移動大量元素
. 當(dāng)線性表長度變化較大時,難以確定存儲空間的容量
. 容易造成存儲空間的”碎片”