Sqlist.h
#ifndef _SQLIST_H_ #define _SQLIST_H_ #define LIST_INIT_SIZE 1 #define LISTINCREAMENT 1 //#define ElemType int typedef struct { char name[20]; int age; }ElemType; /************************************************************************/ /* 存储结构的定义 */ /************************************************************************/ typedef struct { ElemType *elem; /*基址的指针*/ int length; /*表的长度,表中元素的个数*/ int size; /*表的容量*/ }Sqlist; /************************************************************************/ /* 表的基本操作 */ /************************************************************************/ void InitList(Sqlist *L);/*初始化表*/ void DestroyList(Sqlist *L);/*销毁表,释放存储空间*/ void ClearList(Sqlist *L);/*将表置空*/ int IsEmpty(Sqlist *L);/*判断表是否为空,空则返回1,否则返回0 */ int Length(Sqlist *L);/*返回表的长度*/ ElemType *GetElem(Sqlist *L, int i); /*返回表中第i个元素*/ int LocateElem(Sqlist *L, ElemType e);/*判断e是否为表中的元素,是则返回元素在表中的位置,否则返回-1*/ /*用pre_e获取元素e的前驱,返回值i为前驱在表中位置*/ /*如果e不在表中,返回-1 */ /*如果e为表中的第一个元素,返回-2*/ int PriorElem(Sqlist *L, ElemType e, ElemType *pre_e); /*用next_e获取e的后继,返回值i为后继在表中的位置*/ /*如果e不是表中元素,返回-1*/ /*如果e为表中的最后一个元素,返回-2*/ int NextElem(Sqlist *L, ElemType e, ElemType *next_e); /*在位置i处插入元素e,成功则返回表的长度,否则返回0*/ int Insert(Sqlist *L, ElemType e, int i); /*删除表中的元素e,成功返回1,否则返回0*/ int Delete(Sqlist *L, int n, ElemType *e); /*遍历*/ void traverse(Sqlist *L); #endif
Sqlist.c
#include <stdlib.h> #include <stdio.h> #include <string.h> #include "Sqlist.h" /*初始化表*/ void InitList(Sqlist *L) { L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType)); if (!L->elem) { printf("动态内存分配失败 "); exit(0); } L->length = 0; L->size = LIST_INIT_SIZE; } /*销毁表,释放存储空间*/ void DestroyList(Sqlist *L) { if (L->elem) free(L->elem); } /*将表置空*/ void ClearList(Sqlist *L) { if (L->elem) L->length = 0; } /*判断表是否为空,空则返回1,否则返回0 */ int IsEmpty(Sqlist *L) { if (L->elem) { if (L->length > 0) return 0; else return 1; }else return -1; } /*返回表的长度*/ int Length(Sqlist *L) { if (L->elem) return L->length; else return -1; } /*返回表中第i个元素*/ ElemType * GetElem(Sqlist *L, int i) { if (i<1 || i> L->length) { printf("此节点不存在,请检查是否正确!!! "); return NULL; } return &(L->elem[i-1]); } /*判断e是否为表中的元素,是则返回元素在表中的位置,否则返回-1*/ int LocateElem(Sqlist *L, ElemType e) { int i; for (i = 0; i < L->length; i++) { //如果使用e.name == L->elem[i].name 经过测试失败(e.name="chen",同样L->elem[i].name= "chen") //从首地址开始逐个遍历字符比较是可以的,也就是strcmp,string.h if (strcmp(L->elem[i].name,e.name) == 0) return i+1; } return -1; } /*用pre_e获取元素e的前驱,返回值i为前驱在表中位置*/ /*如果e不在表中,返回-1 */ /*如果e为表中的第一个元素,返回-2*/ int PriorElem(Sqlist *L, ElemType e, ElemType *pre_e) { int local; local = LocateElem(L, e); if (local == -1)//表中不存在该元素 return -1; if (local == 1)//表中的第一个元素 return -2; pre_e = &(L->elem[local-1]); //*pre_e = L->elem[local-1] //会出错 return (local-1); } int NextElem(Sqlist *L, ElemType e, ElemType *next_e) { int local; local = LocateElem(L, e); if (local == -1)//表中不存在该元素 return -1; *next_e = L->elem[local+1]; return (local+1); } /* 在位置i处插入元素e,成功则返回表的长度,否则返回0 */ int Insert(Sqlist *L, ElemType e, int i) { ElemType * temp; int cursor; if (i < 1 || i > L->length + 1) { printf(" 插入位置出错啦(温馨提示n个元素,有n+1个插入位置) "); return 0; } /*应该在此添加插入位置是否合法的判断条件*/ if (L->length >= L->size) { /*这个很耗内存,不建议使用realloc*/ temp = (ElemType *)realloc(L->elem, (L->size + LISTINCREAMENT)*sizeof(ElemType)); if (!temp) { printf("动态内存分配失败overflow!!! "); return 0; } L->elem = temp; L->size += LISTINCREAMENT; } /* debug error:Damage before normal block 编译器报这样的错,几乎可以肯定是在程序中,数组访问越界, 这面这个肯定最后一个元素是空数据,或者是垃圾数据 DAMAGE:After normal block(#****) */ for (cursor = L->length-1; cursor >= i-1; cursor --) L->elem[cursor + 1] = L->elem [cursor]; L->elem[i-1] = e; L->length++; return 1; } /* 在位置n处插入元素,并将删除元素保存在e当中 */ int Delete(Sqlist *L, int n, ElemType *e) { int i; if (n < 1 || n > L->length) { printf("删除位置不合法!!! "); return -1; } e = &(L->elem[n-1]); for (i = n-1; i < L->length; i++) L->elem[i] = L->elem[i + 1]; L->length --; return 1; } void traverse(Sqlist *L) { int i = 0; if (!L->elem || L->length ==0) return; for (; i< L->length; i ++) { printf(" 顺序表中第%d个元素分别为:(%s,%d)", i, L->elem[i].name,L->elem[i].age); } printf(" "); }
main.c
#include "Sqlist.h" #include <stdio.h> #include <stdlib.h> #include <malloc.h> int main() { Sqlist L; int i; ElemType e, *ptr_e; InitList(&L); /*测试插入元素,在头元素位置和尾元素单独测试*/ printf("请输入要添加的节点元素: 例如:chen 23 "); for (i = 1; i < 4; i++) { fflush(stdin); scanf("%s%d",&e.name,&e.age); Insert(&L,e,i); } /* //测试第一个位置 printf(" 测试第一个位置插入 "); fflush(stdin); scanf("%s%d",&e.name,&e.age); Insert(&L,e,1); traverse(&L); printf("%d",L.size); printf(" %d ",L.length); //测试最后一个位置 printf(" 测试最后一个位置插入 "); fflush(stdin); scanf("%s%d",&e.name,&e.age); Insert(&L,e,L.length+1); traverse(&L); printf("%d",L.size); printf(" %d ",L.length); */ /* //测试删除第一个元素 Delete(&L,1, &e); traverse(&L); printf("%d",L.size); printf(" %d ",L.length); printf(" 您所删除的元素是:(%s,%d)",e.name,e.age); //测试删除最后一个个元素 Delete(&L,L.length, &e); traverse(&L); printf("%d",L.size); printf(" %d ",L.length); printf(" 您所删除的元素是:(%s,%d)",e.name,e.age); printf(" "); */ /* //测试取出指定位置上的元素; for (i = 1; i < 4; i ++) { e = *GetElem(&L,i); printf(" 您所找的元素是:(%s,%d)",e.name,e.age); } */ /* //测试定位元素 printf("请输入要定位的元素:例如(name age) "); scanf("%s%d",&e.name, &e.age); //如果这个地方丢了&,就会出现unhandle exception i = LocateElem(&L, e); printf(" 元素的位置是:%d", i); */ //测试查找前一个元素 printf("请输入要定位的元素:例如(name age) "); scanf("%s%d",&e.name, &e.age); i = PriorElem(&L, e, ptr_e); printf(" 元素的位置是:%d", i); DestroyList(&L); printf(" "); return 0; }