C資料結構-線性表之順序表
阿新 • • 發佈:2018-12-21
線性表之順序表
順序表使用C語言的原生陣列作為儲存結構,使用者指定陣列的大小,動態的申請堆空間。動態設計的好處比事先用巨集定義規定大小更加靈活,而且支援順序表的重置大小操作。使得使用順序表的人擁有更大的靈活性,節省執行記憶體。順序表結構體的定義使用了柔性陣列,這一點使得我們在操作順序表資料陣列時變得相當簡單。值得講解的有幾個操作:
1. 線性表的重置大小
int seq_list_resize(seq_list *plist, int size);重置大小可以是容量變大或者變小,如果重置的大小與原陣列的大小一致,那將什麼都不做。重置大小之後將會複製舊陣列中的內容到新的陣列中,實質就是呼叫了realloc函式進行重置和複製工作。如果重置的大小小於原來的大小,那麼將發生資料截斷;如果重置的大小大於原來的大小則原來陣列中的所有元素會被保留。
2. 線性表的清空
int seq_list_clear(seq_list *plist);清空資料表的操作,實際上只是將順序表的長度值設定為0,並不實際清除陣列中的內容,因為這麼做毫無意義。
#ifndef SEQLIST_H #define SEQLIST_H #ifndef NULL #define NULL 0 #endif /* 元素型別 */ typedef int elem_t; /* 順序表結構體 */ typedef struct _tag_list { int length;//順序表長度 int capacity;//順序表的最大容量 elem_t data[]; }seq_list; /* * 順序表初始化 * @param size 順序表的大小 * @param return 順序表的指標 */ seq_list *seq_list_init(int size); /* * 插入元素 * @param plist 順序表指標 * @param i 插入位置的索引 * @param e 插入的元素指標 * @return 1:成功 0:失敗 */ int seq_list_insert(seq_list *plist,int i,elem_t *pe); /* * 刪除元素 * @param plist 順序表指標 * @param i 刪除位置的索引 * @param pe 儲存被刪除元素值的指標 * @return 1:成功 0:失敗 */ int seq_list_delete(seq_list *plist,int i,elem_t *pe); /* * 獲取元素 * @param plist 順序表指標 * @param i 獲取位置的索引 * @param pe 儲存元素值的指標 * @return 1:成功 0:失敗 */ int seq_list_get(seq_list *plist,int i,elem_t *pe); /* * 重置順序表大小 * @param plist 順序表指標 * @param size 重置後順序表的最大容量 * @param return 1:成功 0:失敗 */ int seq_list_resize(seq_list *plist, int size); /* * 判斷順序表是否為空 * @param plist 順序表指標 * @return 1:為空 0:不為空 * @return 1:為空 0:不為空 -1:出錯 */ int seq_list_is_empty(seq_list *plist); /* * 獲取順序表的長度 * @param plist 順序表指標 * @return 長度 */ int seq_list_length(seq_list *plist); /* * 獲取順序表的最大容量 * @param plist 順序表指標 * @return 長度 */ int seq_list_max_size(seq_list *plist); /* * 清空順序表 * @param plist 順序表指標 * @param return 1:成功 0:失敗 */ int seq_list_clear(seq_list *plist); /* * 銷燬順序表 */ int seq_list_destroy(seq_list *plist); #endif // SEQLIST
#include "SeqList.h" #include "malloc.h" /* * 順序表初始化 * @param size 順序表的大小 * @param return 順序表的指標 */ seq_list *seq_list_init(int size) { seq_list *plist = (seq_list *)malloc(sizeof(seq_list) + sizeof(elem_t) * size); if(plist) { plist->length = 0; plist->capacity = size; } return plist; } /* * 插入元素 * @param plist 順序表指標 * @param i 插入位置的索引 * @param e 插入的元素指標 * @return 1:成功 0:失敗 */ int seq_list_insert(seq_list *plist,int i,elem_t *pe) { //合法性檢查 int ret = ( (plist != NULL) && (i >= 0) && (i <= plist->length) && (plist->length + 1 <= plist->capacity) ); if(ret) { int pos =0; //從後往前逐個將元素後移 for(pos = plist->length;pos > i;pos--) { plist->data[pos] = plist->data[pos - 1]; } //將元素插入 plist->data[i] = *pe; plist->length++; } return ret; } /* * 刪除元素 * @param plist 順序表指標 * @param i 刪除位置的索引 * @param pe 儲存被刪除元素值的指標 * @return 1:成功 0:失敗 */ int seq_list_delete(seq_list *plist,int i,elem_t *pe) { //合法性檢查 int ret = ( (plist != NULL) && (i >= 0) && (i < plist->length) ); if(ret) { int pos = 0; //儲存被刪除元素的值 *pe = plist->data[i]; //從被刪除索引處開始,將後一位的資料往前移動 for(pos = i;pos < plist->length -1;pos++) { plist->data[pos] = plist->data[pos + 1]; } plist->length--; } return ret; } /* * 獲取元素 * @param plist 順序表指標 * @param i 獲取位置的索引 * @param pe 儲存元素值的指標 * @return 1:成功 0:失敗 */ int seq_list_get(seq_list *plist,int i,elem_t *pe) { //合法性檢查 int ret = ( (plist != NULL) && (i >= 0) && (i < plist->length) ); if(ret) { //儲存元素的值 *pe = plist->data[i]; } return ret; } /* * 判斷順序表是否為空 * @param plist 順序表指標 * @return 1:為空 0:不為空 -1:出錯 */ int seq_list_is_empty(seq_list *plist) { int ret = -1; if(plist != NULL) { ret = (plist->length == 0); } return ret; } /* * 獲取順序表的長度 * @param plist 順序表指標 * @return 長度,-1出錯 */ int seq_list_length(seq_list *plist) { int ret = -1; if(plist != NULL) { ret = plist->length; } return ret; } /* * 重置順序表大小 * @param plist 順序表指標 * @param size 重置後順序表的最大容量 * @param return 1:成功 0:失敗 */ int seq_list_resize(seq_list *plist, int size) { int ret = (plist != NULL && size >0); if(ret && (plist->length != size) ) { int length = plist->length; length = (size > length ? length : size); //重新申請空間,realloc會自動釋放原空間 seq_list *p = realloc(plist,sizeof(seq_list) + sizeof(elem_t) * size); if(p != NULL) { plist = p; plist->length = length; plist->capacity = size; }else { ret = 0; } } return ret; } /* * 獲取順序表的最大容量 * @param plist 順序表指標 * @return 長度,-1出錯 */ int seq_list_max_size(seq_list *plist) { int ret = -1; if(plist != NULL) { ret = plist->capacity; } return ret; } /* * 清空順序表 * @param plist 順序表指標 * @param return 1:成功 0:失敗 */ int seq_list_clear(seq_list *plist) { int ret = (plist != NULL); if(ret) { plist->length = 0; } return ret; } /* * 銷燬順序表 */ int seq_list_destroy(seq_list *plist) { int ret = (plist != NULL); if(ret) { free(plist); plist = NULL; } return ret; }