什么是線性表?
線性表是n個數據元素的有限序列。根據線性表的顯現方式,線性表又分為順序表(數據元素在內存中的存儲空間是連續的)和鏈表(數據元素在內存中的存儲空間是不連續的)。
線性表如何用C語言實現?線性表可以進行哪些操作?
在C語言中,線性表通過結構體的方式來實現。結構體中定義了線性表的存儲空間地址,當前長度,和當前分配的存儲容量。操作包含在指定位置插入某一元素、刪除指定元素、查找指定的元素等。在這里重點介紹插入和刪除算法。
下面就是關於這一部分內容的陳述。
線性表的C語言實現
- 需要先定義好的內容
#define LIST_INIT_SIZE 100 //線性表存儲空間的初始分配量 #define LISTINCREMENT 10 //線性表存儲空間的分配增量 #define OK 1 #define ERROR 0 #define OVERFLOW -2 typedef int Status; typedef int ElemType;
- 定義線性表
typedef struct{ ElemType *elem; int length; int listsize; }SqList;
- 寫一個函數,構造一個空的線性表L
Status InitList_Sq(SqList &L){ L.elem=(ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));//malloc函數為分配一個內存空間 if(!L.elem) exit(OVERFLOW);//存儲分配失敗 L.length=0;//空表的長度為零 L.listsize=LIST_INIT_SIZE;//設置初始分配容量 return OK; }
- 順序表的插入操作
Status ListInsert_Sq(Sqlist *L, int i, ElemType e) { //在順序線性表L中第i個位置之前插入新的元素e //i的合法值為1<=i<=ListLength_Sq(L) + 1 ElemType *newbase, *q, *p; if(i < 1 || i > L->length + 1) return ERROR;//i值不合法 if(L->length >= L->listsize) //當前存儲空間已滿,增加分配 { newbase = (ElemType *)realloc(L->elem, (L->listsize + LISTINCREMENT)*sizeof(ElemType)); if(!newbase) return ERROR; //分配失敗 L->elem = newbase; //新基址 L->listsize += LISTINCREMENT; //增加存儲容量 } q = &L->elem[i-1]; //q為插入位置 for(p = &L->elem[L->length-1]; p >= q; --p) *(p+1) = *p; //插入位置及之后的元素后移 *q = e; //插入e L->length++; //表增長1 return OK; }//ListInsert_Sq
- 順序表的刪除操作
Status ListDelete_Sq(Sqlist *L, ElemType i, ElemType *e) { //在順序線性表L中刪除第i個元素,並用e返回其值 //i的合法值為1<=i<=ListLength_Sq(L) ElemType *p, *q; if(i < 1 || i > L->length + 1) return ERROR;//i 值不合法 p = &L->elem[i-1]; //p為被刪除元素的位置 *e = *p; //被刪除元素的值賦給e q = &L->elem[i] + L->length - 1;//表尾元素的位置 for(++p; p <= q; p++) //++p為要移動元素的第一個 *(p-1) = *p; //元素左移 L->length--; //表長減一 return OK; }//ListDelete_Sq
從順序表的插入和刪除算法可以看出,順序表的插入和刪除操作是通過數據元素的移動來實現的,因此,線性表的插入和刪除的算法時間復雜度都是O(n).此外,順序表還要求系統分配連續的存儲空間,這就給存儲空間的分配提出了更高的要求,而且也容易造成存儲空間的利用率不高等問題。正是由於順序表種種的不方便,所以才引入了鏈表,鏈表的出現解決了很多順序表解決不了的問題,最明顯的變化就是元素存儲空間不需要連續。當然,這需要借助指針來實現,這就引入了新的問題。總體而言,順序表和鏈表各有優缺點,在選擇時,要根據實際情況選擇更加適合的數據結構。