大話資料結構 —— 3.5 順序儲存結構的插入與刪除
阿新 • • 發佈:2018-12-10
3.5.1 獲得元素操作
實現GetElem的具體操作,即將線性表L中的第i個位置元素值返回。就程式而言非常簡單了,我們只需要把陣列第i-1下標的值返回即可。
我們來學習下具體的程式碼:getElem.c
#define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 typedef int Status; // Status是函式的型別,其值是函式結果狀態程式碼,如OK等。 // 初始條件: 順序線性表L已存在, 1 <= i <= ListLength(L) // 操作結果: 用e返回L中第i個數據元素的值。 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是一個整型,約定返回1代表OK,返回0代表ERROR。今後還會出現,也是使用同樣的約定,不再詳述。
3.5.2 插入操作
剛才我們也談到,線性表的順序儲存結構具有隨機儲存結構的特點,時間複雜度為O(1)。
大家現在來考慮下,如果我們要實現 ListInsert(*L, i, e)
即線上性表L中的第i個位置插入新元素e,程式碼應該如何寫?
所以插入演算法的思路:
- 如果插入位置不合理,丟擲異常;
- 如果線性表長度大於等於陣列長度,則丟擲異常或動態增加陣列容量;
- 從最後一個元素開始向前遍歷到第i個位置,分別將它們都向後移動一個位置;
- 將要插入元素填入位置i處;
- 線性表長+1。
接下來看程式碼ListInsert.c
// 初始條件: 順序線性表L已存在, 1 <= i <= ListLength(L) // 操作結果: 在L種第i個位置之前插入新的資料元素e,L長度+1 Status ListInsert(SqList *L, int i, ElemType *e) { int k; if( L->length == MAXSIZE ) // 順序線性表已經滿了 { return ERROR; } if( i<1 || i>L->length+1 ) // 當i不在範圍內時 { return ERROR; } if( i<= L->length ) // 若插入資料位置不在表尾 { // 將刪除位置後繼元素後移 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.5.3 刪除操作
所以刪除演算法的思路:
- 如果刪除位置不合理,丟擲異常;
- 取出刪除元素;
- 從刪除元素位置開始遍歷到最後一個元素位置,分別將它們都向前移動一個位置;
- 表長-1。
實現程式碼: ListDelete.c
// 初始條件: 順序線性表L已存在, 1 <= i <= ListLength(L)
// 操作結果: 刪除L的第i個數據元素,並用e返回其值,L的長度-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;
}
現在我們分析一下,插入和刪除的時間複雜度。
最好的情況:插入和刪除操作剛好要求在最後一個位置操作,因為不需要移動任何元素,所以此時的時間複雜度為O(1)。
最壞的情況:如果要插入和刪除的位置是第一個元素,那就意味著要移動所有的元素向後或者向前,所以這個時間複雜度為0(n)。
至於平均情況,就取中間值O((n-1)/2)。
按照前邊推導大O指導,平均情況複雜度簡化後還是O(n)。
3.5.4 線性表順序儲存結構的優缺點
線性表的順序儲存結構,在存、讀資料時,
不管是哪個位置,時間複雜度都是0(1)。
而在插入或刪除時,時間複雜度都是0(n)。 這就說明,它比較適合元素個數比較穩定,不經常插入和刪除元素,而更多的操作是存取資料的應用。
那我們接下來給大家簡單總結下線性表的順序儲存結構的優缺點:
優點:
- 無須為表示表中元素之間的邏輯關係而增加額外的儲存空間。
- 可以快速地存取表中任意位置的元素。
缺點:
- 插入和刪除操作需要移動大量元素。
- 當線性表長度變化較大時,難以確定儲存空間的容量。
- 容易造成儲存空間的“碎片”