說在前面
資料結構和演算法是程式設計的靈魂。坦誠的說,我在這方面是弱的可以。雖然工作這麼多年了,因為種種借口,這塊知識一直是我的痛處。
曾經在面試時大言不慚的說,這些知識在工作中很少用到,所以當年學習的東西早就還給學校了。其實不然,失去了靈魂的程式員如我,總是要逆襲的。
所以以後的學習中會有一些如孩童筆記般的文章出現在我的blog中,請大師們不要嘲笑,要提攜。
定義
線性表可以說是最簡單的資料結構,它的描述為:n個資料元素的有限序列。
記為:L=(a1,a2,...,an)
按照儲存結構它又可以分為順序儲存結構和鏈式儲存結構。
而其中線性表的順序儲存結構是最簡單最常用的資料結構:用一段連續地址依次儲存表中的資料元素。
看到這裡,我們會自然的聯想到C語言中的數組。
下面我要實現的是線性表中的元素為整型的順序儲存結構,及它的主要運算:增刪查。
先來簡單的定義一下這個線性表的順序儲存結構:
#define MAXLENGTH 20struct sequencelist{int data[MAXLENGTH];int length;};
其中data數組為這個線性表的主要部分,資料元素就存在於此數組中,而對這個線性表的操作都是基於這個數組。
length是這個線性表的一個屬性,表示這個線性表包含元素的個數。
增:線性表的插入操作
對線性表的插入就是對data數組的插入,然後將其length增加。
//insert oprationint insert(struct sequencelist *list,int index,int element){int length = list->length;if(length ==0 || index < 0 || index > length || length >= MAXLENGTH)return ERROR;list->data[index] = element;for(int i = length - 1;i>index;i--){list->data[i+1] = list->data[i];}list->length++;return OK;}刪:線性表的刪除操作
類似增的相反操作。
// Delete oprationint delete(struct sequencelist *list,int index){int length = list->length;if(length ==0 || index < 0 || index > length-1 )return ERROR;for(int i = index;i<length-1;i++){list->data[i] = list->data[i+1];}list->data[length-1] = '\0';//delete the last element.list->length--;return OK;}查:線性表的取元素操作
用索引值尋找元素的值。
//get list elements//make sure elemet is NOT NULL when calling.int getElement(struct sequencelist list,int index,int *element){printf("\ngetElement\n");int length = list.length;printf("length is %d\n",length);if(length ==0 || index < 0 || index >= length)return ERROR;*element = list.data[index];return OK;}
從程式中可以看出增刪操作的時間複雜度都是0(n),所以這兩項操作都是不是它的強項。而尋找操作的時間複雜度是O(1),那麼線性表的順序儲存結構的優勢就是可以快速的取出任意位置的元素。
上面的3種操作作為較為基本的操作,是本人的學習筆記。如果大蝦們發現哪裡有不妥,請不吝賜教。
而線性表的其他動作如求前驅元素、求後驅元素、判斷表中是否存在某元素值、清空操作等等有意思的操作還待空閑時去完成。
較為完整的調試例子:
//2013.2//lincoln//linear list//Sequence Storage Structure //#include <stdio.h>#define OK 1#define ERROR -1#define TURE 1#define FALSE 0#define MAXLENGTH 20struct sequencelist{int data[MAXLENGTH];int length;};//get list elements//make sure elemet is NOT NULL when calling.int getElement(struct sequencelist list,int index,int *element){printf("\ngetElement\n");int length = list.length;printf("length is %d\n",length);if(length ==0 || index < 0 || index >= length)return ERROR;*element = list.data[index];return OK;}//insert opration//int insert(struct sequencelist *list,int index,int element){printf("\ninsert\n");int length = list->length;printf("length is %d\n",length);if(length ==0 || index < 0 || index > length || length >= MAXLENGTH)return ERROR;list->data[index] = element;for(int i = length - 1;i>index;i--){list->data[i+1] = list->data[i];}list->length++;return OK;}// Delete opration//int delete(struct sequencelist *list,int index){printf("\ndelete\n");int length = list->length;printf("length is %d\n",length);if(length ==0 || index < 0 || index > length-1 )return ERROR;for(int i = index;i<length-1;i++){printf("delete data[%d]\n",i);list->data[i] = list->data[i+1];}list->data[length-1] = '\0';//delete the last element.list->length--;return OK;}int main(){struct sequencelist list = {{3,1,5,7,12,78,34},7};printf("list length : %d\n",list.length);//Test getint *element = 0, test = 8;element = &test;if(OK == getElement(list,2,element)){printf("list get 2 :%d\n", *element);}//Test insertif(OK == insert(&list,7,520)){printf("list insert 7 ok!\n");}if(OK == getElement(list,7,element)){printf("list get 7 :%d\n", *element);}if(OK == insert(&list,3,520)){printf("list insert 3 ok!\n");}if(OK == getElement(list,3,element)){printf("list get 3 :%d\n", *element);}//Test deleteif(OK == delete(&list,3)){printf("list delete 3 ok!\n");}if(OK == getElement(list,3,element)){printf("list get 3 :%d\n", *element);}if(OK == delete(&list,6)){printf("list delete 6 ok!\n");}if(OK == getElement(list,6,element)){printf("list get 6 :%d\n", *element);}else{printf("list get ERROR!\n");}}