这是我通过我所学的及参考了一些伪代码后写出的具体实现代码,分享给大家一起互相借鉴,如有写的不好的,多多指教一下,哈哈。
主要实现的有顺序表的构造、初始化、创建、插入、删除、查找和遍历(使用了动态分配的一维数组实现和使用了静态分配的数组实现,具体请看代码)以及顺序表的合并和归并的实现。
代码如下(编写软件为vs2017):
头文件"CAF.h"代码:
#pragma once /* * 名称:《CAF.h》 —— Constants And Functions(常量和函数) * 作用:用来定义顺序表的各种常量和函数 **/ #include <stdio.h> #include <stdlib.h> #include <malloc.h> /* 函数结果状态代码 */ #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define INFEASIBLE -1 #define OVERFLOW -2 #define MAXSIZE 1000 //初始分配量 #define LISTINCREMENT 10 //线性表存储空间的分配增量 typedef int Status; //函数名,返回值为函数结果状态代码 typedef int ElemType; //数据类型 /* 构造顺序表-1 */ typedef struct Sqlist_1 { ElemType data[MAXSIZE]; int length; }Sqlist_1; /* 构造顺序表-2 */ typedef struct Sqlist_2 { ElemType *elem; //存储空间基址 int length; //当前长度 int listsize; //当前分配的存储容量 }Sqlist_2; /* 菜单 */ void Menu(); /* 顺序表的初始化-1 */ Status InitList_Sq1(Sqlist_1 **L1); /* 顺序表的初始化-2 */ Status InitList_Sq2(Sqlist_2 **L2); /* 顺序表的创建-1 */ Status CreateList_Sq1(Sqlist_1 **L1, int len); /* 顺序表的创建-2 */ Status CreateList_Sq2(Sqlist_2 **L2, int len); /* 顺序表的遍历-1 */ void Plist1(Sqlist_1 *L1); /* 顺序表的遍历-2 */ void Plist2(Sqlist_2 *L2); /* 顺序表查找-1 */ Status GetElem1(Sqlist_1 *L1, int i, ElemType *e); /* 顺序表查找-2 */ Status GetElem2(Sqlist_2 *L2, int i, ElemType *e); /* 顺序表插入-1 */ Status ListInsert1(Sqlist_1 **L1, int i, ElemType e); /* 顺序表插入-2 */ Status ListInsert2(Sqlist_2 **L2, int i, ElemType e); /* 顺序表删除-1 */ Status ListDelete1(Sqlist_1 **L1, int i, ElemType *e); /* 顺序表删除-2 */ Status ListDelete2(Sqlist_2 **L2, int i, ElemType *e); /* 合并顺序表 */ void Union(Sqlist_1 **L1, Sqlist_2 *L2); /* 按元素值查找 */ int LocateElem(Sqlist_1 *L1, ElemType e); /* 归并顺序表-1 */ void MergeList(Sqlist_1 *L1, Sqlist_2 *L2, Sqlist_1 **L3); /* 冒泡排序表1和表2 */ void Show(Sqlist_1 **L1, Sqlist_2 **L2); /* 归并顺序表-2 */ void MergeList_sq(Sqlist_1 *L1, Sqlist_2 *L2, Sqlist_2 **L3);
实现函数的文件"CAF.c"代码:
/* * 名称:《CAF.c》 * 作用:实现《CAF.h》中定义的函数 **/ #include "CAF.h" /* 菜单 */ void Menu() { printf("************************* 菜单 *************************\n\n"); printf("1、初始化顺序表\n\n2、创建顺序表\n\n3、遍历顺序表\n\n4、顺序表插入\n\n5、顺序表删除\n\n6、顺序表查找\n\n"); printf("7、合并顺序表\n\n8、归并顺序表\n"); printf("\n********************************************************\n"); } /* 顺序表的初始化-1 */ Status InitList_Sq1(Sqlist_1 **L1) { *L1 = (Sqlist_1 *)malloc(sizeof(Sqlist_1)); if ((*L1) == NULL) exit(OVERFLOW); (*L1)->length = 0; //线性表长度赋为0,空表 return OK; } /* 顺序表的初始化-2 */ Status InitList_Sq2(Sqlist_2 **L2) { *L2 = (Sqlist_2 *)malloc(sizeof(Sqlist_2)); (*L2)->elem = (ElemType *)malloc(MAXSIZE * sizeof(ElemType)); if ((*L2) == NULL) exit(OVERFLOW); if ((*L2)->elem == NULL) exit(OVERFLOW); (*L2)->length = 0; //当前为空表,长度为0 (*L2)->listsize = MAXSIZE; //初始分配存储容量 return OK; } /* 顺序表的创建-1 */ Status CreateList_Sq1(Sqlist_1 **L1, int len) { int i; (*L1)->length = len; printf("**--** 请输入数据创建顺序表1 **--** : "); for (i = 0; i < (*L1)->length; i++) { scanf("%d", &(*L1)->data[i]); } return OK; } /* 顺序表的创建-2 */ Status CreateList_Sq2(Sqlist_2 **L2, int len) { int i; (*L2)->length = len; printf("**--** 请输入数据创建顺序表2 **--** : "); for (i = 0; i < (*L2)->length; i++) { scanf("%d", &(*L2)->elem[i]); } return OK; } /* 顺序表的遍历-1 */ void Plist1(Sqlist_1 *L1) { int i; printf("\n************************** 表中数据 **************************\n\n"); for (i = 0; i < L1->length; i++) { printf("%d ", L1->data[i]); } printf("\n\n***************************************************************\n"); } /* 顺序表的遍历-2 */ void Plist2(Sqlist_2 *L2) { int i; printf("\n************************** 表中数据 **************************\n\n"); for (i = 0; i < L2->length; i++) { printf("%d ", L2->elem[i]); } printf("\n\n***************************************************************\n"); } /* 顺序表查找-1 */ Status GetElem1(Sqlist_1 *L1, int i, ElemType *e) { if (L1->length == 0 || i < 1 || i > L1->length) { return ERROR; } *e = L1->data[i - 1]; return OK; } /* 顺序表查找-2 */ Status GetElem2(Sqlist_2 *L2, int i, ElemType *e) { if (L2->length == 0 || i < 1 || i > L2->length) { return ERROR; } *e = L2->elem[i - 1]; return OK; } /* 顺序表插入-1 */ Status ListInsert1(Sqlist_1 **L1, int i, ElemType e) { int k; if ((*L1)->length == MAXSIZE) //表满 { return ERROR; } if (i < 1 || i >(*L1)->length + 1) //i不在范围 { return ERROR; } if (i <= (*L1)->length) //插入位置不在表尾 { //插入位置后所有元素后移一位 for (k = (*L1)->length - 1; k >= i - 1; k--) { (*L1)->data[k + 1] = (*L1)->data[k]; } } (*L1)->data[i - 1] = e; //插入新元素 (*L1)->length++; //表长+1 return OK; } /* 顺序表插入-2 */ Status ListInsert2(Sqlist_2 **L2, int i, ElemType e) { ElemType *q; //q为插入位置 ElemType *p; if (i < 1 || i >(*L2)->length + 1) //i不合法 return ERROR; if ((*L2)->length >= (*L2)->listsize) //空间已满,增加分配 { ElemType *newbase; newbase = (ElemType *)realloc((*L2)->elem, ((*L2)->listsize + LISTINCREMENT) * sizeof(ElemType)); if (newbase == NULL) exit(OVERFLOW); //分配失败 (*L2)->elem = newbase; //新基址 (*L2)->listsize += LISTINCREMENT; //增加存储容量 } q = &(*L2)->elem[i - 1]; for (p = &(*L2)->elem[(*L2)->length - 1]; p >= q; p--) //插入位置及之后的元素右移 *(p + 1) = *p; *q = e; //插入e (*L2)->length++; //表长+1 return OK; } /* 顺序表删除-1 */ Status ListDelete1(Sqlist_1 **L1, int i, ElemType *e) { int k; if ((*L1)->length == 0) return ERROR; if (i < 1 || i > (*L1)->length) return ERROR; *e = (*L1)->data[i - 1]; if (i < (*L1)->length) { for (k = i; k < (*L1)->length; k++) { (*L1)->data[k - 1] = (*L1)->data[k]; } } (*L1)->length--; return OK; } /* 顺序表删除-2 */ Status ListDelete2(Sqlist_2 **L2, int i, ElemType *e) { ElemType *p; ElemType *q; if (i < 1 || i >(*L2)->length) return ERROR; p = &(*L2)->elem[i - 1]; //被删除元素的位置 *e = *p; //被删除元素赋给e q = (*L2)->elem + (*L2)->length - 1; //表尾元素的位置 for (++p; p <= q; p++) { *(p - 1) = *p; } (*L2)->length--; return OK; } /* 合并顺序表 */ void Union(Sqlist_1 **L1, Sqlist_2 *L2) { //将所有在表2中但不在表1中的数据元素插入到表1中 ElemType e2; int i; int L1_len, L2_len; //求顺序表长度 L1_len = (*L1)->length; L2_len = L2->length; for (i = 1; i <= L2_len; i++) { GetElem2(L2, i, &e2); //取表2中第i个元素赋给e2 if (!LocateElem(*L1, e2)) //如果表达式为真,则L1中不存在和e相同的元素,则插入其中 { ListInsert1(L1, ++L1_len, e2); } } } /* 按元素值查找 */ int LocateElem(Sqlist_1 *L1, ElemType e) { int i = 0; while (i < L1->length && L1->data[i] != e) { i++; } if (i >= L1->length) return 0; //没找到相同的,返回假 else return i + 1; //找到相同的,返回真 } /* 归并顺序表 */ void MergeList(Sqlist_1 *L1, Sqlist_2 *L2, Sqlist_1 **L3) { //已知顺序表L1和L2中的数据元素按值非递减排列 //归并L1和L2得到新的顺序表L3,L3的数据元素也按值非递减排列 ElemType ai, bj; //InitList_Sq1(L3); //初始化L3 int i = 1, j = 1, k = 0; int L1_len, L2_len; L1_len = L1->length; L2_len = L2->length; while ((i <= L1_len) && (j <= L2_len)) //L1和L2均非空 { GetElem1(L1, i, &ai); GetElem2(L2, j, &bj); if (ai <= bj) { ListInsert1(L3, ++k, ai); ++i; } else { ListInsert1(L3, ++k, bj); ++j; } } //插入剩余元素 while (i <= L1_len) { GetElem1(L1, i++, &ai); ListInsert1(L3, ++k, ai); } while (j <= L2_len) { GetElem2(L2, j++, &bj); ListInsert1(L3, ++k, bj); } } /* 冒泡排序表1和表2 */ void Show(Sqlist_1 **L1, Sqlist_2 **L2) { int i1, j1, i2, j2; int N1, N2; ElemType temp1, temp2; N1 = (*L1)->length; N2 = (*L2)->length; for (i1 = 0; i1 < N1 - 1; i1++) { for (j1 = 0; j1 < N1 - i1 - 1; j1++) { if ((*L1)->data[j1] > (*L1)->data[j1 + 1]) { temp1 = (*L1)->data[j1]; (*L1)->data[j1] = (*L1)->data[j1 + 1]; (*L1)->data[j1 + 1] = temp1; } } } printf("表1排序后:"); Plist1(*L1); printf("\n-------------------------------------------------------\n\n"); for (i2 = 0; i2 < N2 - 1; i2++) { for (j2 = 0; j2 < N2 - i2 - 1; j2++) { if ((*L2)->elem[j2] >(*L2)->elem[j2 + 1]) { temp2 = (*L2)->elem[j2]; (*L2)->elem[j2] = (*L2)->elem[j2 + 1]; (*L2)->elem[j2 + 1] = temp2; } } } printf("表2排序后:"); Plist2(*L2); printf("\n-------------------------------------------------------\n\n\n"); } /* 归并顺序表-2 */ void MergeList_sq(Sqlist_1 *L1, Sqlist_2 *L2, Sqlist_2 **L3) { //已知顺序表L1和L2中的数据元素按值非递减排列 //归并L1和L2得到新的顺序表L3,L3的数据元素也按值非递减排列 ElemType *pa, *pb, *pc; ElemType *pa_last, *pb_last; pa = L1->data; //表一元素的首地址 pb = L2->elem; //表二元素的首地址 (*L3)->listsize = (*L3)->length = L1->length + L2->length; //新表初始分配长度 pc = (*L3)->elem = (ElemType *)malloc((*L3)->listsize * sizeof(ElemType)); //分配空间 if (!((*L3)->elem)) exit(OVERFLOW); //存储分配失败 pa_last = L1->data + L1->length - 1; //表一最后一个元素的地址 pb_last = L2->elem + L2->length - 1; //表二最后一个元素的地址 while (pa <= pa_last && pb <= pb_last) //归并 { if (*pa <= *pb) *pc++ = *pa++; else *pc++ = *pb++; } while (pa <= pa_last) //插入表1的剩余元素 { *pc++ = *pa++; } while (pb <= pb_last) //插入表2的剩余元素 { *pc++ = *pb++; } }
主函数代码:
#include <stdio.h> #include <stdlib.h> #include "CAF.h" /* * * 项目名称:【 顺序表的基本操作实现及其使用 】 * 【说明】: * < 1.实现顺序表的构造、初始化、创建、插入、删除、查找、遍历这几项基本操作 > * < 2.实现了顺序表的合并和顺序表的归并 > * 作者:踏歌行彡轻盈 * 日期:2018-4-23 * **/ int main() { Sqlist_1 *L1; Sqlist_2 *L2; Sqlist_1 *L3; Sqlist_2 *L4; int len1, len2; //要创建的顺序表的长度1和长度2 int choice; //菜单选择 int e, i; int e1, i1; Menu(); //菜单 while (1) { printf("\n\n*-** 请选择(按数字0退出) **-* "); fflush(stdin); scanf("%d", &choice); fflush(stdin); printf("\n"); switch (choice) { case 1: /* 使用两种方式初始化顺序表 */ InitList_Sq1(&L1); InitList_Sq2(&L2); InitList_Sq1(&L3); InitList_Sq2(&L4); break; case 2: /* 使用两种方式创建顺序表 */ printf("请输入要创建的顺序表的长度1和长度2: "); fflush(stdin); scanf("%d%d", &len1, &len2); fflush(stdin); CreateList_Sq1(&L1, len1); CreateList_Sq2(&L2, len2); break; case 3: /* 遍历顺序表 */ printf("|** --------------------------------------------------------------------- **|\n"); printf("\n|*|- *************************** 遍历顺序表 *************************** -|*|\n\n"); Plist1(L1); printf("\n|** --------------------------------------------------------------------- **|\n"); Plist2(L2); if (L3->length != 0) { printf("\n|** --------------------------------------------------------------------- **|\n"); Plist1(L3); } if (L4->length != 0) { printf("\n|** --------------------------------------------------------------------- **|\n"); Plist2(L4); } printf("\n\n|** --------------------------------------------------------------------- **|\n"); break; case 4: printf("|** --------------------------------------------------------------------- **|\n\n"); printf("\n--**-- 请输入表1要插入的元素和要插入的位置 --**-- : "); fflush(stdin); scanf("%d%d", &e, &i); fflush(stdin); ListInsert1(&L1, i, e); Plist1(L1); printf("\n\n|**| -------------------------------------------------------------- |**|\n\n"); printf("\n--**-- 请输入表2要插入的元素和要插入的位置 --**-- : "); fflush(stdin); scanf("%d%d", &e, &i); fflush(stdin); ListInsert2(&L2, i, e); Plist2(L2); printf("\n\n|** --------------------------------------------------------------------- **|\n"); break; case 5: printf("|** --------------------------------------------------------------------- **|\n\n"); printf("\n--**-- 请输入表一中要删除的元素位置:"); fflush(stdin); scanf("%d", &i); fflush(stdin); ListDelete1(&L1, i, &e1); printf("|-**-| 被删除的元素为:%d |-**-|\n\n", e1); printf("|*-*------------------------ 删除后 ------------------------*-*|\n\n"); Plist1(L1); printf("\n\n|**| -------------------------------------------------------------- |**|\n\n"); printf("\n--**-- 请输入表二中要删除的元素位置:"); fflush(stdin); scanf("%d", &i); fflush(stdin); ListDelete2(&L2, i, &e1); printf("|-**-| 被删除的元素为:%d |-**-|\n\n", e1); printf("|*-*------------------------ 删除后 ------------------------*-*|\n\n"); Plist2(L2); printf("\n\n|** --------------------------------------------------------------------- **|\n"); break; case 6: printf("|** --------------------------------------------------------------------- **|\n\n"); printf("\n请输入在表一中要查找的元素的位置:"); fflush(stdin); scanf("%d", &i1); fflush(stdin); GetElem1(L1, i1, &e1); printf("该位置的元素为:%d\n", e1); printf("\n\n|**| -------------------------------------------------------------- |**|\n\n"); printf("\n请输入在表二中要查找的元素的位置:"); fflush(stdin); scanf("%d", &i1); fflush(stdin); GetElem2(L2, i1, &e1); printf("该位置的元素为:%d\n", e1); printf("\n\n|** --------------------------------------------------------------------- **|\n"); break; case 7: printf("|** --------------------------------------------------------------------- **|\n\n"); printf("\n|**|-*-*-*-*-*-*-*-*-*-*- 将表2合并到表1前 -*-*-*-*-*-*-*-*-*-*-|**|\n\n"); Plist1(L1); printf("\n|** --------------------------------------------------------------------- **|\n"); Plist2(L2); printf("\n\n|** --------------------------------------------------------------------- **|\n"); printf("\n\n|**|-*-*-*-*-*-*-*-*-*-*- 将表2合并到表1后 -*-*-*-*-*-*-*-*-*-*-|**|\n\n"); Union(&L1, L2); Plist1(L1); printf("\n\n|** --------------------------------------------------------------------- **|\n"); break; case 8: printf("|** --------------------------------------------------------------------- **|\n\n\n"); Show(&L1, &L2); printf("|*-*|-*-*-*-*-*-*-*-*-*-*-*-*- 归并方法一 - 将表1和表2归并到表3后 -*-*-*-*-*-*-*-*-*-*-*-*-|*-*|\n\n"); MergeList(L1, L2, &L3); Plist1(L3); printf("\n|** --------------------------------------------------------------------- **|\n"); printf("|*-*|-*-*-*-*-*-*-*-*-*-*-*-*- 归并方法二 - 将表1和表2归并到表4后 -*-*-*-*-*-*-*-*-*-*-*-*-|*-*|\n\n"); MergeList_sq(L1, L2, &L4); Plist2(L4); printf("\n\n|** --------------------------------------------------------------------- **|\n"); break; case 0: return 0; break; } } return 0; }
程序运行效果截图: