前记:
现在我在学习数据结构与算法,所以计划记录下学习中的心得,以便以后回忆,博客是一个不错的平台,方便学习。
问题描述:
设某线性表数据元素的类型为整型,以顺序表为存储结构,编程实现。
数据类型定义:
(一)、数据结构:用顺序结构保存线性表,建立结构,带头结点,
/*-------定义线性表的元素类型,此处为整形-------------------- */
typedef int Elemtype;
/*-------------- 线性表的动态分配顺序存储结构-------------------*/
typedef struct {
Elemtype *elem; /* 存储空间的首地址 */
int length; /* 当前长度 */
int listsize; /* 当前分配的存储空间 */
}SqList;
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
#define LISTINCREMENT 10 // 线性表存储空间的分配增量//状态结果的代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW –1
-
函数原型:
//-----------基本的操作--------------------------------- //构造一个空的线性表 int InitList(SqList *L); //销毁线性表L,L已经存在 int DestroyList(SqList *L); //将表L置空,线性表L已经存在 int ClearList(SqList *L); //判断L是否为空,空返回true,否则false,L已经存在 int ListEmpty(SqList L); //返回L中元素的个数,L已经存在 int ListLength(SqList L); //用e返回L中的第i个元素的值,成果返回true.1<=i<=Lenth int GetElem(SqList L, int i, Elemtype *e); //返回L中第一个与e满足关系compare()的数据的位(1,2,...), //不成功返回0, L已经存在,compare()为判定函数 int LocateElem(SqList L,Elemtype e,int (*compare)(void *, void *)); //若cur_e是L的数据元素,且不是第一个,则用pre_e返回他的 //前驱,否则返回失败,pre_e无定义,L存在 int PriorElem(SqList L, Elemtype cur_e, Elemtype *pre_e); //若cur_e是L的数据元素,且不是最后一个,则用next_e返回他的 //后继,否则返回失败,next_e无定义,L存在 int NextElem(SqList L, Elemtype cur_e, Elemtype *next_e); //在L的第i个位置插入新的元素e,L的长度加一,L已经存在 //1<=i<=listlength+1,成功返回ture int ListInsert(SqList *L, int i, Elemtype e); //删除L的第i个元素,用e保存,L长度减一 //线性表L已经存在非空,1<=i<=listlength int ListDelete(SqList *L, int i, Elemtype *e); //依次对L调用函数visit(),失败就操作失败,L已经存在 int ListTraverse(SqList L, int (* visit)(void *)); //显示线性表中的所有元素 int ListPrint(SqList L); //保存线性表到文件 int ListSave(SqList L); //导入线性表文件 int ListLoad(SqList *L);源代码:
//构造一个空的线性表 int InitList(SqList *L) { L->elem = (Elemtype *)malloc(LIST_INIT_SIZE * sizeof(Elemtype)); if (!L->elem) exit(ERROR); //存储分配失败 L->length = 0; //设置长度 L->listsize = LIST_INIT_SIZE; //设置已经分配的空间 return OK; // 成功时返回OK } //销毁线性表L,L已经存在,存储空间释放掉 int DestroyList(SqList *L) { if (!L->elem) //已经销毁 return ERROR; free(L->elem); L->elem = NULL; /* 表置空*/ return OK; } //将表L置空,线性表L已经存在,长度置零 int ClearList(SqList *L) { if (!L->elem) //L不存在 return ERROR; L->length = 0; return OK; } //判断L是否为空,空返回true,否则false,L已经存在 int ListEmpty(SqList L) { if (L.length < 0 || L.length > L.listsize || !L.elem) return ERROR; if (L.length == 0) return TRUE; return FALSE; } //返回L中元素的个数,L已经存在 int ListLength(SqList L) { if (L.length < 0 || L.length > L.listsize || !L.elem) return ERROR; return L.length; } //用e返回L中的第i个元素的值,成果返回true. 1<=i<=Lenth int GetElem(SqList L, int i, Elemtype *e) { if (i < 1 || i > L.length || !L.elem) return FALSE; *e = (int )L.elem[i-1]; /* 与Elemtype 相关*/ return TRUE; } //返回L中第一个与e满足关系compare()的数据的位(1,2,...), //不成功返回0, L已经存在,compare()为判定函数 int LocateElem(SqList L,Elemtype e,int (*compare)(void *, void *)) { int i; if (!L.elem) return ERROR; for (i = 0; i < L.length; i++) { if (compare((int *)e, (int *)L.elem[i]) == TRUE) /* 与Elemtype 相关*/ return i+1; } return 0; } //若cur_e是L的数据元素,且不是第一个,则用pre_e返回他的 //前驱,否则返回失败,pre_e无定义,L存在 int PriorElem(SqList L, Elemtype cur_e, Elemtype *pre_e) { int i; for (i = 1; i < L.listsize; i++) { if (L.elem[i] == cur_e) { *pre_e = (int )L.elem[i-1]; /* 与Elemtype 相关*/ return OK; } } return FALSE; } //若cur_e是L的数据元素,且不是最后一个,则用next_e返回他的 //后继,否则返回失败,next_e无定义,L存在 int NextElem(SqList L, Elemtype cur_e, Elemtype *next_e) { int i; for (i=0; i < L.listsize - 1; i++) { if (L.elem[i] == cur_e) { *next_e = (int )L.elem[i+1]; /* 与Elemtype 相关*/ return OK; } } return FALSE; } //在L的第i个位置插入新的元素e,L的长度加一,L已经存在 //1<=i<=listlength+1,成功返回ture int ListInsert(SqList *L, int i, Elemtype e) { if (!L->elem) return ERROR; Elemtype *newbase, *target, *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(-1); L->elem = newbase; L->listsize += LISTINCREMENT; } target = &(L->elem[i-1]); //target 为插入的地址 for (p = &(L->elem[L->length-1]); p >= target; p--) *(p+1) = *p; *target = e; ++L->length; return OK; } //删除L的第i个元素,用e保存,L长度减一 //线性表L已经存在非空,1<=i<=listlength int ListDelete(SqList *L, int i, Elemtype *e) { Elemtype *tail, *p; if (i < 1 || i > L->length || !L->elem) return ERROR; p = &(L->elem[i-1]); e = p; tail = &(L->elem[L->length-1]); for (p++; p <= tail; ++p) *(p-1) = *p; --L->length; return OK; } //依次对L调用函数visit(),失败就操作失败,L已经存在 int ListTraverse(SqList L, int (* visit)(void *)) { int i; for (i = 0; i < L.length; i++) //如果失败 if (!visit((int *)L.elem[i]))/* 与Elemtype 相关*/ return ERROR; return TRUE; } //显示线性表中的所有元素 int ListPrint(SqList L) { int i; if (!L.elem || L.length < 1 || L.length > L.listsize){ printf("empty!\n"); return ERROR; } for (i = 0; i < L.length; i++) { printf("%d ", L.elem[i]); } printf("\n"); return TRUE; } //保存线性表元素int ListSave(SqList L) {char fileName[FILENAME_MAX]; int i; FILE *fout; printf("input the file(输入文件名):\n"); scanf("%s", fileName); if ((fout = fopen(fileName, "w+")) == NULL) { printf("error!\n"); return ERROR; } fprintf(fout, "%d %d\n", L.length, L.listsize); for (i=0; i < ListLength(L); i++){ fprintf(fout, "%d\t", L.elem[i]); } fclose(fout); return OK; } //导入文件信息 int ListLoad(SqList *L) { char fileName[FILENAME_MAX]; int i; FILE *fin; printf("input the file(输入文件名):\n"); scanf("%s", fileName); if ((fin = fopen(fileName, "r+")) == NULL) { printf("error!\n"); return ERROR; } fscanf(fin, "%d %d\n", &L->length, &L->listsize); for (i=0; i < L->length; i++){ fscanf(fin, "%d\t", &L->elem[i]); } fclose(fin); return OK; }//界面函数void printMain(void){
system("cls");
printf("--------------欢迎来到线性表操作界面--------------------\n");
printf(" ----design by lijian\n");
printf("\n\
(1) 导入文件构造一个空线性表\n\
(2) 销毁线性表\n\
(3) 线性表置空\n\
(4) 判断是否为空\n\
(5) 求线性表长度\n\
(6) 返回线性表的某元素的值\n\
(7) 返回线性表中第一个给定元素满足关系compare()\n\
(8) 返回它的前驱\n\
(9) 返回他的后继\n\
(10) 数据元素的插入操作\n\
(11) 数据元素的删除操作\n\
(12) 依次对线性表调用函数visit()\n\
(13) 显示线性表中的全部元素\n\
(14) 保存线性表到文件\n\
(0 ) 退出\n");
printf("输入你的选择(0-14):\n");
return ;
}//主函数int main(void)
{
SqList L;
int choose = -1;
Elemtype element, searchElem;
int num;
system("color 0a"); /* 设置界面颜色 */
InitList(&L);
do {
printMain();
scanf("%d", &choose);
fflush(stdin); //刷新输入流
switch (choose) {
case 0: printf("hope you enjoy this journey!\n"); break;
case 1: if (ListLoad(&L)) printf("success to load\n");
else printf("error!\n");
system("pause"); break;
case 2: if (DestroyList(&L)) printf("success to destroy\n");
system("pause"); break;
case 3: if (ClearList(&L)) printf("success to clear\n");
system("pause"); break;
case 4: if (ListEmpty(L)) printf(" empty\n");
else printf("not empty!\n");
system("pause"); break;
case 5: printf ("the length is %d\n", ListLength(L));
system("pause"); break;
case 6: printf("输入元素位置,(1-%d):\n", ListLength(L));
scanf("%d", &num);
if (GetElem(L, num, (int *)&element))
printf("元素是 %d\n", element);
else printf("错误!\n");
system("pause");
break;
case 7: /* 进行一些函数调用 */
/*LocateElem(L, element, compare);*/
break;
case 8:
printf("输入元素对象:\n");
scanf("%d", &searchElem);
if (PriorElem(L, searchElem, (int *) &element))
printf("它的前一个元素是 %d\n", element);
else printf("没有!\n");
system("pause");
break;
case 9:
printf("输入元素对象:\n");
scanf("%d", &searchElem);
if (NextElem(L, searchElem, (int *)&element))
printf("它的后一个元素是 %d\n", element);
else printf("没有!\n");
system("pause"); break;
case 10:
printf("输入插入元素的位置,(1-%d):\n", 1 + ListLength(L));
scanf("%d", &num);
printf("输入元素:\n");
scanf("%d", &element);
if (ListInsert(&L, num, element)) printf("success to insert\n");
else printf("fail to insert!\n");
system("pause"); break;
case 11:
printf("输入要删除元素的位置,(1-%d):\n", ListLength(L));
scanf("%d", &num);
if (ListDelete(&L, num, (int *)&element)) printf("succes to delete\n");
else printf("fail to delete\n");
system("pause"); break;
case 12: /* 对每个元素调用一次函数 */
/* ListTraverse(L, visit); */
system("pause"); break;
case 13:
ListPrint(L);
system("pause"); break;
case 14:
if (ListSave(L)) printf("success to save!\n");
else printf("error!\n");
system("pause"); break;
default: system("pause"); break;
}
}while (choose != 0);system("pause");
return 0;
}
- 实现效果:
界面:
导入:
显示: