一、線性表的概念:
1、線性表是一種最簡單、最常用的數據結構,通常一個線性表是由n(n>=0)個性質相同的數據元素組成的有限序列,長度即爲元素的個數n,當n=0時,稱該表爲空表。
2、非空的線性結構的特點:它具有惟一的第一個數據元素和最後一個數據元素;並且除了第一個元素以外,其他數據元素都只有一個前驅和一個後繼。
3、線性表的主要存儲結構:順序存儲結構 和 鏈式存儲結構。(本篇主要總結順序存儲結構)
二、線性表的順序表示和實現
順序存儲結構的存儲可以用一維數組表示,具有固定長度。
也可以用動態分配的存儲結構,可以合理地利用空間。
(一)一維數組表示
數據結構:
typedef int datatype; #define LIST_MAXSIZE 100 typedef struct { datatype data[LIST_MAXSIZE]; int length; }Sqlist;
|
基本操作:
/*表的初始化*/ void InitList(Sqlist *L) { L->length() = 0; } /*求表長*/ int ListLength(Sqlist *L) { return L->length; } /*求表中的第i個節點*/ datatype GetElem(Sqlist *L,int i) { if(i<1 || i>L->length) Error("position error"); return L->data[i-1]; } /*查找節點x在表中的第一個位置*/ int Search(int x,Sqlist *L) { int i; for(i=0;i<L->length;i++) if(x == L->data[i]) break; if(i == L->length) return 0; else retrun i+1; } /*在線性表中的第i個位置之前插入元新元素e*/ Status Insert_Sq(Sqlist *L,int i,datatype e) { datatype * q, *p; if(i<1 || i>L->length) return ERROR; if(L->length > LIST_MAXSIZE-1) retrun ERROR; q = &(L->data[i-1])//插入的位置
for(p=&(L->data[L->length-1]);p>=q;--p) { *(p+1) = *p; } *q = e; ++L->length; return OK; } /*第i個節點的刪除*/ Status Delete_Sq(Sqlist *L,int i) { datatype * p,*q; if(i<1 || i>L->length) return ERROR; p = &(L->data[i-1])//要刪除節點的位置
q = &(L->data[L->length-1])//表尾元素的位置
for(;p<q;p++) { *p = *(p+1); } --L->length; return OK; }
|
歸併操作:
/*已知線性表La和Lb非遞減排序,歸併La和Lb得到Lc的數據元素也按非遞減排序*/ Void MergeList(Sqlist *La,Sqlist *Lb,Sqlist *Lc) { int La_len,Lb_len,i=j=1,k=0; datatype ai,bj; La_len = ListLength(La); Lb_len = ListLength(Lb); while((i<=la_len)&&(i<=lb_len)) { ai = GetElem(La,i); bj = GetElem(Lb,j); if(ai < bj) { k++; i++; ListInsert(Lc,ai); } else { k++; j++; ListInsert(Lb,bj); } } while(i<=La_len) { ai = GetElem(La,i); i++; k++; ListInsert(Lc,ai); } while(j<=Lb_len) { bj = GetElem(Lb,j); j++; k++; ListInsert(Lc,bj); } Lc->length = k; }
|
以上算法在《數據結構(c語言版)》陳明編著清華大學出版 33頁上分了三種情況,ai<bj,ai=bj,ai>bj.其實ai=bj這種情況沒必要單獨列出來,當然這樣思路更清晰點,程序如下:
/*已知線性表La和Lb非遞減排序,歸併La和Lb得到Lc的數據元素也按非遞減排序*/ Void MergeList(Sqlist *La,Sqlist *Lb,Sqlist *Lc) { int La_len,Lb_len,i=j=1,k=0; datatype ai,bj; La_len = ListLength(La); Lb_len = ListLength(Lb); while((i<=la_len)&&(i<=lb_len)) { ai = GetElem(La,i); bj = GetElem(Lb,j); if(ai < bj) { k++; i++; ListInsert(Lc,ai); } else if(ai == bj) { k++; ListInsert(Lc,ai); i++; k++; ListInsert(Lc,bi); j++; } else { k++; j++; ListInsert(Lb,bj); } } while(i<=La_len) { ai = GetElem(La,i); i++; k++; ListInsert(Lc,ai); } while(j<=Lb_len) { bj = GetElem(Lb,j); j++; k++; ListInsert(Lc,bj); } Lc->length = k; }
|
利用基本運算清除線性表中重複出現的多餘節點
void Purge(List *L) { int i,k; datatype x,y; for(i=1;i<ListLength(L);i++) { x = GetElem(L,i); k = i+1; while(k<=ListLength(L)) { y = GetElem(L,k); if(x==y) Delete(L,k); else k++; } } }
|
該算法的關鍵是Delete()算法中 會自動把l->length減1。