經過三天的時間終於把順序表的操作實現搞定了。(主要是在測試部分停留了太長時間)
1. 線性表順序存儲的概念:指的是在內存中用一段地址連續的存儲單元依次存儲線性表中的元素。
2. 采用的實現方式:一段地址連續的存儲單元可以用固定數組或者動態存儲結構來實現,這里采用動態分配存儲結構。
3. 順序表結構體示意圖

三種寫法完整代碼:
第一種寫法. 從鍵盤輸入生成線性表--完整代碼如下,取值操作實際上就是刪除操作的部分實現,這里就不寫了
#include<stdio.h> #include<stdlib.h> #include<malloc.h> #define LIST_INIT_SIZE 100 #define LISTINCREMENT 10 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 #define TRUE 1 #define FALSE 0 typedef int Status; typedef int ElemType; typedef struct SqList { ElemType *elem; int length; int listsize; }SqList; Status InitList(SqList &L) { L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType)); if (!L.elem) { printf("ERROR\n"); return ERROR; } L.length = 0; L.listsize = LIST_INIT_SIZE; return OK; } Status ListEmpty(SqList L) //判空 { if (L.length = 0) return TRUE; else return FALSE; } Status ListInsert(SqList &L, int i, ElemType e) //插入 { ElemType *p, *q; ElemType *newbase; int j; if (i < 1 || i > L.length + 1) return ERROR; if (L.length >= L.listsize){ newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType)); if (newbase == NULL) { printf("realloc failed!\n"); return ERROR;//exit(-1); } L.elem = newbase; L.listsize += LISTINCREMENT; } p = L.elem+i-1; for( q = L.elem + L.length - 1; q>= p; --q ) { *(q+1) = *q; } *p = e; ++L.length; return OK; } Status CrtList(SqList &L) // 從鍵盤輸入數據生成線性表 { printf("輸入整數,以0結束:\n"); ElemType e; int i = 1; scanf("%d", &e); while (e != 0) { if (!ListInsert(L, i, e)) return ERROR; i++; scanf("%d", &e); } return OK; } Status CrtList2(SqList &L, ElemType d[], int n) // 從數組生成線性表 { int i; for (i = 0; i < n; ++i) { if (!ListInsert(L, i + 1, d[i])) return ERROR; } return OK; } Status ListDelet(SqList &L, int i, ElemType &e) //刪除 { if ((i<1) || (i>L.length)) return ERROR; ElemType *p, *q; p = &(L.elem[i - 1]); e = *p; q = L.elem + L.length - 1; for (++p; p <= q; ++p) *(p - 1) = *(p); --L.length; return OK; } Status GetElem(SqList &L, int i, ElemType &e) //取值 { if ((i <= 0) || (i>L.length)) return ERROR; else { e = L.elem[i - 1]; return OK; } } Status compare(ElemType a, ElemType b) //比較 { if (a == b) return TRUE; else return FALSE; } int LocateElem(SqList L, ElemType e) //定位 { Status compare(ElemType a, ElemType b); int i; for (i = 0; i<L.length; i++) { if (compare(L.elem[i], e)) return ++i; } if (i == L.length) return 0; } Status PriorElem(SqList L, ElemType cur_e, ElemType &pre_e) //求直接前驅 { int LocateElem(SqList L, ElemType e); int i = LocateElem(L, cur_e); if ((i == 0) || (i == 1)) return ERROR; pre_e = L.elem[i - 2]; return OK; } int ListLength(SqList L) //求長度 { int length = L.length; return length; } void MergeList(SqList La, SqList Lb, SqList &Lc) //歸並 { Lc.length = La.length + Lb.length; Lc.listsize = Lc.length; Lc.elem = (ElemType*)malloc(Lc.length*sizeof(ElemType)); if (Lc.elem == NULL) exit(OVERFLOW); int i, j, k; for (i = 0, j = 0, k = 0; (i<La.length) && (j<Lb.length); k++) { if (La.elem[i]<Lb.elem[j]) { Lc.elem[k] = La.elem[i]; i++; } else { Lc.elem[k] = La.elem[j]; j++; } } while (i<La.length) { Lc.elem[k] = La.elem[i]; i++; k++; } while (j<Lb.length) { Lc.elem[k] = Lb.elem[j]; j++; k++; } } void vist(ElemType e) { printf("%d ", e); } Status ListTraverse(SqList L) //遍歷 { int i; if (L.length == 0) printf("無元素"); for (i = 0; i<L.length; i++) { vist(L.elem[i]); } if (i == L.length) { printf("\n"); return OK; } else return ERROR; } Status ListClear(SqList L) //清空 { if (L.elem == NULL) return ERROR; int i; for (i = 0; i<L.length; i++) L.elem[i] = 0; L.length = 0; return OK; } Status DestroyList(SqList &L) //銷毀 { if (L.elem == NULL) return ERROR; free(L.elem); L.length = 0; L.listsize = 0; return OK; } void PrnList(SqList L) //打印 { int i; for (i = 0; i < L.length; ++i){ printf("%5d", L.elem[i]); } printf("\n"); } int main() { int j, l; ElemType e, e1; SqList La; if (InitList(La)) printf("OK\n"); else exit(INFEASIBLE); CrtList(La); PrnList(La); int k; printf("1:判空\n2:插入\n3:刪除\n4:定位\n5:求長度\n6:直接前驅\n"); printf("7:歸並\n8:遍歷\n9:清空\n10:銷毀\n\n0:退出\n"); scanf("%d", &k); while (k != 0) { switch (k) { case 1: if (ListEmpty(La)) printf("empty\n"); else printf("non-empty\n"); break; case 2: printf("在第幾個位置插入何數:"); scanf("%d%d", &j, &e); if (ListInsert(La, j, e)) printf("OK\n"); else printf("ERROR\n"); break; case 3: printf("刪除第幾個數:"); scanf("%d", &j); if (ListDelet(La, j, e)) PrnList(La); printf("刪除數為:%d\n", e); break; case 4: printf("定位數字:"); scanf("%d", &e); if (LocateElem(La, e) != 0) printf("OK,位序為:%d\n", LocateElem(La, e)); else printf("ERROR\n"); break; case 5: l = ListLength(La); printf("ListLength=%d\n", l); break; case 6: printf("尋找何數直接前驅:"); scanf("%d", &e); if (PriorElem(La, e, e1)) printf("前驅為:%d\n", e1); else printf("ERROR\n"); break; case 7: SqList Lb, Lc; if (InitList(Lb)) printf("OK\n"); else printf("ERROR\n"); CrtList(Lb); MergeList(La, Lb, Lc); printf("有序歸並后:\n"); PrnList(Lc); break; case 8: if (ListTraverse(La)) printf("遍歷成功\n"); else printf("遍歷失敗\n"); break; case 9: if (ListClear(La)) printf("清空成功\n"); else printf("清空失敗\n"); break; case 10: if (DestroyList(La)) printf("銷毀完成\n"); else printf("銷毀失敗\n"); return 0; default: printf("ERROR\n"); } scanf("%d", &k); } return 0; }
第二種寫法. 從txt文件讀入生成線性表--完整代碼如下:
#include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define OVERFLOW -1 #define TRUE 1 #define FALSE 0 #define INIT_LIST_SIZE 100 #define LISTINCREMENT 10 typedef int Status; typedef int ElemType; typedef struct{ ElemType *elem; int length; int listsize; }SqList; Status InitList(SqList *L) { L->elem = (ElemType*)malloc(INIT_LIST_SIZE*sizeof(ElemType)); if (!L->elem) exit(OVERFLOW); L->length = 0; L->listsize = INIT_LIST_SIZE; return OK; } Status ListEmpty(SqList L) //判空 { if (L.length = 0) return TRUE; else return FALSE; } Status ListInsert(SqList *L, int i, ElemType e) //插入 { ElemType *newbase, *q, *p; if (i<1 || i>L->length + 1) return ERROR; if (L->length>L->listsize) { newbase = (ElemType*)realloc(L->elem, (L->listsize + LISTINCREMENT)*sizeof(ElemType)); if (!newbase) exit(OVERFLOW); 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; ++L->length; return OK; } Status ListDelete(SqList *L, int i, ElemType * e) //刪除 { ElemType * p, *q; if (i<1 || i>L->length) return ERROR; p = L->elem + i - 1; //p為被刪除元素位置 *e = *p; //被刪除元素的值賦值給e q = L->elem + L->length - 1; //表尾元素位置 for (++p; p <= q; ++p) { *(p - 1) = *p; } L->length--; return OK; } Status GetElem(SqList *L, int i, ElemType * e) //取值 { if (i<1 || i>L->length) return ERROR; *e = *(L->elem + i - 1); //獲取第i個元素的地址 return OK; } int LocateElem(SqList L, ElemType e) //定位 { int i; for (i = 0; i<L.length; i++) { if (L.elem[i]==e) return ++i; } if (i == L.length) return 0; } Status PriorElem(SqList L, ElemType e, ElemType &pre_e) //求直接前驅 { int LocateElem(SqList L, ElemType e); int i = LocateElem(L, e); if ((i == 0) || (i == 1)) return ERROR; pre_e = L.elem[i - 2]; return OK; } Status GetLength(SqList *L) //求長度 { return L->length; } void PrnList(SqList *L) //遍歷 { int i; for (i = 0; i<(*L).length; i++) { if (i == 0)printf("("); printf(" %d ", L->elem[i]); if (i == (*L).length - 1)printf(")\n"); } } Status ClearList(SqList *L) //清空 { L->length = 0; return OK; } Status Destroy(SqList *L) //銷毀 { free(L->elem); L->elem = NULL; L->length = 0; L->listsize = 0; return OK; } int main() { int n = 0, rc; int a, i; int e, e1; SqList L; if (InitList(&L)) printf("OK\n"); FILE *fp = fopen("D:/1.txt", "r"); if (fp == NULL) { printf("打開文件失敗"); } printf("從1.txt文件讀入幾個數:"); scanf("%d", &n); for (i = 0; i< n; i++) { fscanf(fp, "%d", &a); ListInsert(&L, i+1, a); } fclose(fp); PrnList(&L); char k; printf("\n1.插入\n2.刪除\n3.取值\n4.定位\n5.直接前驅\n6.求長度\n7.遍歷\n8.清空\n9.銷毀\n"); while (1){ k = getchar(); switch (k){ case '1': printf("在第幾個位置插入何數:"); scanf("%d%d", &i, &e); if (ListInsert(&L, i, e))printf("i=%d,e=%d 已經插入\n", i, e); else printf("插入失敗\n"); break; case '2': printf("刪除第幾個數:\n"); scanf("%d", &i); if (ListDelete(&L, i, &e))printf("i=%d,e=%d 已經刪除\n", i, e); else printf("刪除失敗\n"); break; case '3': printf("取第幾個數:\n"); scanf("%d", &i); if (GetElem(&L, i, &e))printf("第i=%d號,e=%d 被取出!\n", i, e); else printf("取值失敗\n"); break; case '4': printf("定位數字:"); scanf("%d", &e); if (LocateElem(L, e) != 0) printf("OK,位序為:%d\n", LocateElem(L, e)); else printf("ERROR\n"); break; case '5': printf("尋找何數直接前驅:"); scanf("%d", &e); if (PriorElem(L, e, e1)) printf("前驅為:%d\n", e1); else printf("ERROR\n"); break; case '6': printf("表長為%d\n", GetLength(&L)); break; case '7': printf("遍歷:\n"); PrnList(&L); break; case '8': if (ClearList(&L)) printf("清空成功\n"); else printf("清空失敗\n"); break; case '9': printf("銷毀\n"); Destroy(&L); printf("銷毀成功\n"); exit(0); return 0; } } return 0; }
第三種寫法:讀數組生成線性表--完整代碼如下:
#include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define OVERFLOW -1 #define TRUE 1 #define FALSE 0 #define INIT_LIST_SIZE 100 #define LISTINCREMENT 10 typedef int Status; typedef int ElemType; typedef struct{ ElemType *elem; int length; int listsize; }Sqlist; Status InitList(Sqlist *L) { L->elem = (ElemType *)malloc(INIT_LIST_SIZE *sizeof(ElemType)); if (!L->elem)exit(OVERFLOW); L->length = 0; L->listsize = INIT_LIST_SIZE; return OK; } Status ListEmpty(Sqlist L) { if (L.length = 0)return ERROR; else return FALSE; } Status ListInsert(Sqlist *L, int i, ElemType e) { ElemType *newbase, *p, *q; if (i<1 || i>L->length + 1)return ERROR; if (L->length > L->listsize) { newbase = (ElemType *)realloc(L, (L->listsize + LISTINCREMENT)*sizeof(ElemType)); if (!newbase)exit(OVERFLOW); L->elem = newbase; L->listsize += LISTINCREMENT; } p = L->elem + i - 1; for (q = L->elem + L->length - 1; q >= p; q--) { *(q + 1) = *q; } *p = e; L->length++; return OK; } Status CreateList(Sqlist *L, ElemType element[], int n) // 從數組生成線性表 { int i; for (i = 0; i < n; ++i) { if (!ListInsert(L, i + 1, element[i])) return ERROR; } return OK; } Status ListDelete(Sqlist *L, int i, ElemType *e) { ElemType *p, *q; if (i<1 || i>L->length)return ERROR; p = L->elem + i - 1; q = L->elem + L->length - 1; *e = *p; for (p++; q >= p; p++) { *(p - 1) = *p; } L->length--; return OK; } Status GetElem(Sqlist *L, int i, ElemType *e) { if (i<1 || i>L->length)return ERROR; *e = L->elem[i - 1]; return OK; } int LocateElem(Sqlist L, ElemType e) { int i; for (i = 0; i < L.length; i++) if (L.elem[i] == e)return i + 1; } Status PriorElem(Sqlist L, ElemType e, ElemType &pr_e) { int LocateElem(Sqlist L, ElemType e); int i = LocateElem(L, e); if (i<1 || i>L.length)return ERROR; pr_e = L.elem[i - 2]; return OK; } Status GetLength(Sqlist *L) { return L->length; } void PrnList(Sqlist *L) { int i; for (i = 0; i < L->length; i++) printf("%d ", L->elem[i]); printf("\n"); } Status ClearList(Sqlist *L) { L->length = 0; return OK; } Status Destroy(Sqlist *L) { free(L->elem); L->elem = NULL; L->length = 0; L->listsize = 0; return OK; } int main() { int i; int a, n = 0; int e, e1; Sqlist L; ElemType element[] = { 15, 3, 59, 27, 8, 11, 32 }; if (InitList(&L))printf("OK\n"); CreateList(&L, element, 7); PrnList(&L); char k; printf("\n1.插入\n2.刪除\n3.取值\n4.定位\n5.直接前驅\n6.求長度\n7.遍歷\n8.清空\n9.銷毀\n"); while (1) { k = getchar(); switch (k) { case '1': printf("在第幾個位置插入何數:"); scanf("%d%d", &i, &e); if (ListInsert(&L, i, e))printf("i=%d e=%d已經插入\n", i, e); break; case '2': printf("刪除第幾個數:"); scanf("%d", &i); if (ListDelete(&L, i, &e))printf("i=%d e=%d已經刪除\n", i, e); break; case '3': printf("取第幾個數:"); scanf("%d", &i); if (GetElem(&L, i, &e))printf("第i=%d e=%d已經取出\n", i, e); break; case '4': printf("定位何數:"); scanf("%d", &e); if (LocateElem(L, e))printf("位序為:%d\n", LocateElem(L, e)); break; case '5': printf("尋找何數的直接前驅:"); scanf("%d", &e); if (PriorElem(L, e, e1))printf("前驅為:%d\n", e1); break; case '6': printf("表長為:%d\n", GetLength(&L)); break; case '7': printf("遍歷:\n"); PrnList(&L); break; case '8': if (ClearList(&L))printf("清空成功!\n"); break; case '9': if (Destroy(&L))printf("銷毀成功!\n"); exit(0); return 0; } } return 0; }
看懂了左手給你個栗子,給我關注點贊;看不懂右手給你個錘子,砸開腦殼看看有沒有帶腦子。
