数据结构——顺序表的实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构——顺序表的实现相关的知识,希望对你有一定的参考价值。
/* 线性结构的基本特征: 1. 集合中必存在唯一的一个“第一元素” 2. 集合中必存在唯一的一个“最后元素” 3. 除最后元素之外,均有唯一的后继 4. 除第一元素之外,均有唯一的前驱 对线性表的基本操作: {结构初始化} InitList(&L); //构造一个空的线性表L {结构的销毁} DestroyList(&L); //销毁线性表L {引用型操作} ListEmpty(L); //线性表判空 ListLength(L); //返回线性表长度 PriorElem(L, cur_e, &pre_e); //返回当前元素前驱 NextElem(L, cur_e, &next_e); //返回当前元素后继 GetElem(L, i, &e); //返回第i个元素的值 Locate(L, e.compare()); //返回 L中第1个与e满足关系compare()的元素的位序,若不存在,返回0 ListTraverse(L, visit()); //遍历线性表 {加工型操作} ClearList(&L); //将L重置为空表 ListInsert(&L, i, e); //在第i个元素之前插入新的元素e,L的长度加1 ListDelete(&L, i, &e); //删除L的第i个元素,并用e返回,L的长度减1 */ #include<stdio.h> #include<stdlib.h> //定义数据类型 typedef int ElemType; //顺序表的存储结构 #define LIST_INIT_SIZE 10 //线性表存储空间的初始分配量 #define LISTINCREMENT 7 //线性表存储空间的分配增量 typedef struct { ElemType *elem; //存储空间基址 int length; //线性表当前长度 int listsize; //线性表当前的存储容量(以sizeof(ElemType)为单位) }SqList; //声明,指针函数 bool (*compare)(ElemType e1, ElemType e2); void (*visit)(ElemType e); //声明,辅助函数 bool equals(ElemType e1, ElemType e2); void visitElem(ElemType e); //声明,对线性表的基本操作 //将有返回值的方法写成ElemType f(),即return (ElemType)i,可能效果更好一些 bool InitList(SqList &L); //初始化一个空表 bool DestroyList(SqList &L); //销毁线性表 bool ListEmpty(SqList L); //线性表判空 int ListLength(SqList L); //线性表长度 void PriorElem(SqList L, ElemType cur_e, ElemType &pre_e); //返回当前元素的前驱 void NextElem(SqList L, ElemType cur_e, ElemType &next_e); //返回当前元素的后继 void getElem(SqList L, int i, ElemType &e); //返回第i个元素的值,0表示第一个元素 void getTail(SqList L, ElemType &e); //返回第最后一个元素 void getHead(SqList L, ElemType &e); //返回第一个元素 int LocateElem(SqList L, ElemType e, bool (*compare)(ElemType e1, ElemType e2)); //返回线性表中与e满足compare关系的第一个元素的位置 void ListTraverse(SqList L, void (*visit)(ElemType e)); //遍历线性表 void ClearList(SqList &L); //将线性表置空 void ListInsert(SqList &L, int i, ElemType e); //在第i个元素之前插入 void AppendTail(SqList &L, ElemType e); //在表尾插入,即插入为最后一个元素 void AppendHead(SqList &L, ElemType e); //在表头插入,即插入为第一个元素 void ListDelete(SqList &L, int i, ElemType &e); //删除第i个元素,并用返回删除的元素 void DeleteTail(SqList &L, ElemType &e); //删除表尾元素,即删除最后一个元素 void DeleteHead(SqList &L, ElemType &e); //删除表头元素,即删除第一个元素 //测试模块 int main(){ SqList L; InitList(L); //给线性表中插入元素,遍历 for (int i = 1; i < 18; i++){ if (i % 3 == 0) AppendTail(L, i); else if (i % 4 == 0) ListInsert(L, 3, i); else AppendHead(L, i); } ListTraverse(L, visitElem); printf("\n\n"); //求第一个元素前驱(返回错误),除第一个元素外其他元素的前驱,线性表中不存在的元素的前驱( //返回错误) ElemType e; ElemType e1; PriorElem(L, 12, e); printf("12的前驱是:%d\n\n", e); getHead(L, e1); PriorElem(L, e1, e); printf("%d的前驱是:%d\n\n", e1, e); PriorElem(L, 21, e); printf("21的前驱是:%d\n\n", e); //求最后一个元素后继(返回错误),除最后一个元素外其他元素后继,线性表中不存在的元素的后继( //返回错误) NextElem(L, 12, e); printf("12的后继是:%d\n\n", e); getTail(L, e1); NextElem(L, e1, e); printf("%d的后继是:%d\n\n", e1, e); NextElem(L, 21, e); printf("21的后继是:%d\n\n", e); //删除第一个元素,删除最后一个元素,删除其他元素,删除超出线性表长度的元素(返回错误) DeleteHead(L, e); printf("删除的元素是:%d\n\n", e); DeleteTail(L, e); printf("删除的元素是:%d\n\n", e); ListDelete(L, 3, e); printf("删除的元素是:%d\n\n", e); ListDelete(L, 21, e); printf("删除的元素是:%d\n\n", e); ListTraverse(L, visitElem); printf("\n\n"); system("pause"); return 0; } //各函数定义模块 bool equals(ElemType e1, ElemType e2){ if (e1 == e2) return true; else return false; } void visitElem(ElemType e){ printf("%4d", e); } bool InitList(SqList &L){ //初始化一个空表 L.elem = (ElemType*)malloc(sizeof(ElemType)*LIST_INIT_SIZE); if (!L.elem) return false; L.length = 0; L.listsize = LIST_INIT_SIZE; return true; } bool DestroyList(SqList &L){ //销毁线性表 if (L.elem){ free(L.elem); return true; } return false; } bool ListEmpty(SqList L){ //线性表判空 if (L.length == 0) return true; else return false; } int ListLength(SqList L){ //线性表长度 return L.length; } void PriorElem(SqList L, ElemType cur_e, ElemType &pre_e){ //返回当前元素的前驱 int curPos = LocateElem(L, cur_e, equals); if (curPos > 0){ pre_e = L.elem[curPos - 1]; } else{ if (curPos == 0){ printf("当前元素是线性表中第一个元素,没有后继\n"); pre_e = -1; } else{ printf("线性表中不存在该元素!\n"); pre_e = -1; } } } void NextElem(SqList L, ElemType cur_e, ElemType &next_e){ //返回当前元素的后继 int curPos = LocateElem(L, cur_e, equals); if (curPos > -1 && curPos < L.length - 1){ next_e = L.elem[curPos + 1]; } else{ if (curPos == L.length - 1){ printf("当前元素是线性表中最后一个元素,没有前驱\n"); next_e = -1; } else{ printf("线性表中不存在该元素!\n"); next_e = -1; } } } void getElem(SqList L, int i, ElemType &e){ //返回第i个元素的值,0表示第一个元素 if (i<1 || i>L.length){ printf("当前索引超出线性表的范围!\n"); return; } e = L.elem[i - 1]; } void getTail(SqList L, ElemType &e){ //返回第最后一个元素 getElem(L, L.length, e); } void getHead(SqList L, ElemType &e){ //返回第一个元素 getElem(L, 1, e); } int LocateElem(SqList L, ElemType e, bool(*compare)(ElemType e1, ElemType e2)){ //返回线性表中与e满足compare关系的第一个元素的位置 for (int i = 0; i < L.length; i++){ if (compare(e, L.elem[i])) return i; } return -1; } void ListTraverse(SqList L, void(*visit)(ElemType e)){ //遍历线性表 for (int i = 0; i < L.length; i++){ if (i % 4 == 0) printf("\n"); visit(L.elem[i]); } } void ClearList(SqList &L){ //将线性表置空 L.length = 0; } void ListInsert(SqList &L, int i, ElemType e){ //在第i个元素之前插入 //判断插入的位置是否合法 if (i<1 || i>L.length + 1){ printf("插入的位置不合法!\n"); return; } //判断链表的存储空间是否足够 if (L.length >= L.listsize){ ElemType *newElem = (ElemType*)realloc(L.elem, (L.listsize + LISTINCREMENT)*sizeof(ElemType)); if (!newElem) return; L.elem = newElem; L.listsize += LISTINCREMENT; } ElemType *iPos = &L.elem[i - 1]; ElemType *tailPos = L.elem + L.length - 1; for (; tailPos >= iPos; tailPos--) *(tailPos + 1) = *tailPos; *iPos = e; L.length++; } void AppendTail(SqList &L, ElemType e){ //在表尾插入,即插入为最后一个元素 ListInsert(L, L.length + 1, e); } void AppendHead(SqList &L, ElemType e){ //在表头插入,即插入为第一个元素 ListInsert(L, 1, e); } void ListDelete(SqList &L, int i, ElemType &e){ //删除第i个元素,并用返回删除的元素 //判断删除的位置是否合法 if (i<1 || i>L.length){ printf("删除的位置不合法!\n"); e = -1; return; } ElemType *iPos = &L.elem[i - 1]; ElemType *tailPos = L.elem + L.length - 1; e = *iPos; for (; iPos <= tailPos; iPos++) *iPos = *(iPos + 1); L.length--; } void DeleteTail(SqList &L, ElemType &e){ //删除表尾元素,即删除最后一个元素 ListDelete(L, L.length, e); } void DeleteHead(SqList &L, ElemType &e){ //删除表头元素,即删除第一个元素 ListDelete(L, 1, e); }
不积跬步,无以至千里;不积小流,无以成江海。从简单的开始,坚持着。
以上是关于数据结构——顺序表的实现的主要内容,如果未能解决你的问题,请参考以下文章