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