C语言实现顺序表的基本操作(从键盘输入 生成线性表,读txt文件生成线性表和数组生成线性表----三种写法)
经过三天的时间终于把顺序表的操作实现搞定了。(主要是在测试部分停留了太长时间)
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; }
看懂了左手给你个栗子,给我关注点赞;看不懂右手给你个锤子,砸开脑壳看看有没有带脑子。
-----------------------------------------------------转载需备注博主名和原创网址!!!------------------------------------------------------