順序表
要點
順序表是在計算機內存中以數組的形式保存的線性表,是指使用一組地址連續的存儲單元依次存儲數據元素的線性結構。
順序表的存儲結構可表示如下:
| #define MAXSIZE 10 typedef int ElemType; typedef struct { // 順序表的結構類型 ElemType data[MAXSIZE]; int length; } SqList; |
基本算法
插入數據元素
在順序表的第 pos(0≤pos≤length) 個位置上插入新的元素e。
如果 pos 值不正確,則返回ERROR;
否則,講順序表中原來第 pos 個元素及以后元素均后移一個位置,騰出一個空位置插入新元素,並且順序表長度增1。
| STATU insertElem(SqList *pList, int pos, ElemType elem) { int i = 0;
// 判斷要插入的位置是否合理 if (pos < 0 || pos > pList->length) return ERROR;
// 將data[pos]及后面的元素都向后移動一個位置 for (i = pList->length - 1; i > pos; i--) { pList->data[i] = pList->data[i-1]; } pList->data[pos] = elem; pList->length++; // 順序表長度加1 return OK; } |
刪除數據元素
刪除順序表中的第 pos(0≤pos≤length-1) 個元素。
如果 pos 值不正確,則返回ERROR;
否則,將順序表中的第 pos 個元素以后的元素均向前移動一個位置,這樣覆蓋了原來的第 pos個元素,並且順序表長度減1。
| STATU removeElem(SqList *pList, int pos, ElemType *pElem) { int i = 0;
// 判斷要刪除的位置是否合理 if (pos < 0 || pos > pList->length) return ERROR;
*pElem = pList->data[pos]; // 將data[pos]后面的元素都向前移動一個位置 for (i = pos; i < pList->length; i++) { pList->data[i] = pList->data[i+1]; } pList->length--; // 順序表長度減1
return OK; } |
參考代碼
以下為本人實現的順序表的基本操作。歡迎指正。本人的編譯環境為Visual Studio2010,C語言。
基本操作
| /*********************************************************************************************************************** [順序表操作] [1] initList, 初始化一個空的順序表 [2] createList, 根據數組 elems 構建一個順序表 [3] insertElem, 在順序表中第 pos 個位置插入元素 elem [4] removeElem, 在順序表中移除第 pos 個元素,並由 pElem 返回其值 [5] getElem, 獲取順序表上位置為 pos 的元素,並由 pElem 返回其值 [6] locateElem, 獲取元素 elem 在順序表上第一次出現的位置,如果不存在返回 -1 [7] printList, 打印整個順序表 ***********************************************************************************************************************/ #include "stdafx.h" #include <stdio.h> #include <stdlib.h>
/*********************************************************************************************************************** 第一部分,數據結構、宏定義 ***********************************************************************************************************************/ #define MAXSIZE 10
typedef enum { // 狀態碼 OK = 0, ERROR = 1 } STATU;
typedef enum { // C語言中沒有bool型,為方便,自定義一個BOOL型 TRUE = 0, FALSE = -1 } BOOL;
typedef int ElemType; // 元素類型 typedef struct { // 順序表的結構類型 ElemType data[MAXSIZE]; int length; } SqList;
/*********************************************************************************************************************** 第二部分,函數實現 ***********************************************************************************************************************/ /******************************************************************************* Funtion : initList Description : 初始化一個空的順序表 Input : SqList *pList Output : SqList *pList Return Value : void Author : VictorZhang Date : 2015-04-10 *******************************************************************************/ void initList(SqList *pList) { pList->length = 0; }
/******************************************************************************* Funtion : createList Description : 根據數組 elems 構建一個順序表 Input : SqList *pList, ElemType elems[], int size Output : SqList *pList Return Value : STATU(OK/ERROR) Author : VictorZhang Date : 2015-04-10 *******************************************************************************/ STATU createList(SqList *pList, ElemType elems[], int size) { int i = 0;
// 判斷數組大小是否超過最大限制 if (size > MAXSIZE) return ERROR;
for (i = 0; i < size; i++) { pList->data[i] = elems[i]; } pList->length = size; return OK; }
/******************************************************************************* Funtion : insertElem Description : 在順序表中第 pos 個位置插入元素 elem Input : SqList *pList, int pos, ElemType elem Output : SqList *pList Return Value : STATU(OK/ERROR) Author : VictorZhang Date : 2015-04-10 *******************************************************************************/ STATU insertElem(SqList *pList, int pos, ElemType elem) { int i = 0;
// 判斷要插入的位置是否合理 if (pos < 0 || pos > pList->length) return ERROR;
// 將data[pos]及后面的元素都向后移動一個位置 for (i = pList->length - 1; i > pos; i--) { pList->data[i] = pList->data[i-1]; } pList->data[pos] = elem; pList->length++; // 順序表長度加1 return OK; }
/******************************************************************************* Funtion : removeElem Description : 在順序表中移除第 pos 個元素,並由 pElem 返回其值 Input : SqList *pList, int pos, ElemType *pElem Output : SqList *pList, ElemType *pElem Return Value : STATU(OK/ERROR) Author : VictorZhang Date : 2015-04-10 *******************************************************************************/ STATU removeElem(SqList *pList, int pos, ElemType *pElem) { int i = 0;
// 判斷要刪除的位置是否合理 if (pos < 0 || pos > pList->length) return ERROR;
*pElem = pList->data[pos]; // 將data[pos]后面的元素都向前移動一個位置 for (i = pos; i < pList->length; i++) { pList->data[i] = pList->data[i+1]; } pList->length--; // 順序表長度減1
return OK; }
/******************************************************************************* Funtion : getElem Description : 獲取順序表上位置為 pos 的元素,並由 pElem 返回其值 Input : SqList list, int pos, ElemType *pElem Output : ElemType *pElem Return Value : STATU(OK/ERROR) Author : VictorZhang Date : 2015-04-10 *******************************************************************************/ STATU getElem(SqList list, int pos, ElemType *pElem) { // 判斷位置是否合理 if (pos < 0 || pos > list.length - 1) return ERROR;
*pElem = list.data[pos]; return OK; }
/******************************************************************************* Funtion : locateElem Description : 獲取元素 elem 在順序表上第一次出現的位置,如果不存在返回 -1 Input : SqList list, ElemType elem Output : N/A Return Value : int Author : VictorZhang Date : 2015-04-10 *******************************************************************************/ int locateElem(SqList list, ElemType elem) { int pos = 0; for (pos = 0; pos < list.length; pos++) { if (elem == list.data[pos]) return pos; } return -1; }
/******************************************************************************* Funtion : printList Description : 打印整個順序表 Input : SqList list Output : N/A Return Value : N/A Author : VictorZhang Date : 2015-04-10 *******************************************************************************/ void printList(SqList list) { int i = 0; if (0 == list.length) { printf("SqList is empty\n"); return; }
printf("SqList:"); for (i = 0; i < list.length; i++) { printf(" %d", list.data[i]); } printf("\n"); } |
測試例部分
/*********************************************************************************************************************** 第三部分,測試例 ***********************************************************************************************************************/ void testCase0() { printf("================== testCase0 ==================\n"); ElemType A[MAXSIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; SqList list = {0}; // 初始化鏈表 initList(&list); printf("Init DList\n"); printList(list); // 根據一個數組來創建順序表 int size = sizeof(A)/sizeof(ElemType); createList(&list, A, size); printf("Create List:\n"); printList(list); // 再次初始化鏈表 initList(&list); printf("Init DList\n"); printList(list); } void testCase1() { printf("================== testCase1 ==================\n"); STATU statu; ElemType A[5] = {0, 1, 2, 3, 4}; SqList list = {0}; // 初始化鏈表 initList(&list); printf("Init DList\n"); printList(list); // 根據一個數組來創建順序表 int size = sizeof(A)/sizeof(ElemType); createList(&list, A, size); printf("Create List:\n"); printList(list); // 在尾部位置嘗試插入元素 statu = insertElem(&list, 5, 5); printf("Insert element:\n"); if (OK != statu) { printf("Insert failed!\n"); } else { printList(list); } // 在頭部位置嘗試插入元素 statu = insertElem(&list, 0, -1); printf("Insert element:\n"); if (OK != statu) { printf("Insert failed!\n"); } else { printList(list); } // 在中間位置嘗試插入元素 statu = insertElem(&list, 3, 11); printf("Insert element:\n"); if (OK != statu) { printf("Insert failed!\n"); } else { printList(list); } // 嘗試在不合理的位置上插入元素 statu = insertElem(&list, 99, 15); if (OK != statu) { printf("Insert failed!\n"); } else { printList(list); } } void testCase2() { printf("================== testCase2 ==================\n"); STATU statu; ElemType elem; ElemType A[5] = {0, 1, 2, 3, 4}; SqList list = {0}; // 初始化鏈表 initList(&list); printf("Init DList\n"); printList(list); // 根據一個數組來創建順序表 int size = sizeof(A)/sizeof(ElemType); createList(&list, A, size); printf("Create List:\n"); printList(list); // 嘗試移除尾部位置的元素 statu = removeElem(&list, 4, &elem); printf("Remove element pos(%d)\n", 4); if (OK != statu) { printf("Remove failed!\n"); } else { printList(list); } // 嘗試移除頭部位置的元素 statu = removeElem(&list, 0, &elem); printf("Remove element pos(%d)\n", 0); if (OK != statu) { printf("Remove failed!\n"); } else { printList(list); } // 嘗試移除中間位置的元素 statu = removeElem(&list, 1, &elem); printf("Remove element pos(%d)\n", 1); if (OK != statu) { printf("Remove failed!\n"); } else { printList(list); } // 嘗試移除不合理位置的元素 statu = removeElem(&list, 11, &elem); printf("Remove element pos(%d)\n", 11); if (OK != statu) { printf("Remove failed!\n"); } else { printList(list); } } void testCase3() { printf("================== testCase3 ==================\n"); STATU statu; ElemType elem; ElemType A[5] = {0, 1, 2, 3, 4}; SqList list = {0}; // 初始化鏈表 initList(&list); printf("Init DList\n"); printList(list); // 根據一個數組來創建順序表 int size = sizeof(A)/sizeof(ElemType); createList(&list, A, size); printf("Create List:\n"); printList(list); // 獲取指定位置上的元素 int pos = 3; statu = getElem(list, pos, &elem); if (OK != statu) { printf("Get element failed!\n"); } else { printf("The elem in pos(%d) is %d\n", pos, elem); } // 查找元素在雙鏈表中第一次出現的位置 elem = 4; pos = locateElem(list, elem); printf("%d is in pos(%d) of SqList\n", elem, pos); elem = 9; pos = locateElem(list, elem); printf("%d is in pos(%d) of SqList\n", elem, pos); } int _tmain(int argc, _TCHAR* argv[]) { testCase0(); testCase1(); testCase2(); testCase3(); return 0; }
參考資料
《數據結構習題與解析》(B級第3版),李春葆、喻丹丹
相關閱讀
歡迎閱讀 程序員的內功——數據結構和算法 系列
