嘻嘻,大家好,新人报到,之前逛,一直很羡慕前辈们能够将自己所精通的知识分享给大家,今天我终于也可以发表属于自己的博客了,嘿嘿,很激动! 这篇博客是数据结构(C语言版)严蔚敏 吴伟民著 书中线性表一章的顺序存储结构实现及其基本操作的实现,发布的有些晚了,希望对大家有一些用吧,代码中还存在一些不完善的地方,希望大家发现了能给我指正一下,谢谢!(另外,因为学业的关系,未来发布的博客也都是以这类为主的,啥时候更新嘛,看情况喽!)
分配内存空间后先检查是否初始化成功,若成功将线性表当前长度初始化为零,线性表总长度设置为LISTINCREMENT(宏定义的值),然后通过while循环依次在线性表中的连续存储空间中存储数据,并检查 数据是否重复,完成以上操作后返回OK,存储在标志K中,代表顺序表初始化初始化成功
Status InitList(Sqlist *L) { ElemType x; L->elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType)); if(!L->elem) { printf("初始化线性表失败\n"); exit(OVERFLOW);//存储空间满了,退出整个程序 } L->length=0; L->listsize=LIST_INIT_SIZE; printf("请输入数字,退出输入负数\n"); while(TRUE) { printf("输入第%d个数字\n",L->length+1); if(L->length<L->listsize) { scanf("%d",&x); if(x>=0) { if(L->length==0) {//当线性表长度为0时,一定不会有重复的元素,可以直接将x存储 L->elem[L->length]=x; L->length++; }else//判断是否重复 { ElemType i,k=1; for(i=0;i<L->length;i++) {//遍历已存储的数据,判断是否有与x重复的数据 if(x==L->elem[i]) k=0; } if(k==0) { printf("输入了重复元素,请重新输入\n"); }else { L->elem[L->length]=x; L->length++; } } } }else { printf("超出长度,请增加线性表长度再赋值\n"); break; } if(x<0)//为了退出初始化函数 break; } return OK; }释放系统分配的连续的内存空间,将基地址赋值为NULL,线性表当前长度赋值为0,总长度赋值为0,并返回一个宏定义的值ERROR给K,代表线性表已销毁。
Status DestroyList(Sqlist *L) { free(L->elem); L->elem=NULL; L->length=0; L->listsize=0; return ERROR; }清空线性表只需要将线性表的当前长度设置为0即可,不用删除其中存储的元素,因为以后为线性表赋值会覆盖原来的数据,省去了删除操作,最后返回一个宏定义的值ERROR给K,代表线性表为空
Status ClearList(Sqlist *L) { L->length=0; return ERROR; }只需要判断线性表的当前长度是否为0,并返回相应的状态即可
Status ListEmpty(Sqlist *L) { if(L->length!=0) return OK; else return ERROR; }返回线性表的当前长度length即可
Status ListLength(Sqlist *L) { printf("线性表的长度为%d\n",L->length); return L->length; }用户输入想要查找的位置,在函数中先判断位置是否合法,(位置是否大于0并小于等于length) 如果合法输出所在位置的元素,不合法输出未找到该位置,并结束调用
void GetElem(Sqlist *L, ElemType position) {//位置的取值肯定是第一个(0)到最后一个(L->length)之间元素 if(position>0&&position<=L->length) printf("你所查找位置的元素值为%d\n",(*L).elem[position-1]); else printf("该位置不存在于线性表中\n"); }先设置一个标志k=0;通过for循环遍历线性表,如果存在该元素,则输出该元素的位置,并令k=1;break出for循环,此时判断k的值是否改变,如果未在线性表中找到该元素,则k的值不会改变
void LocateElem(Sqlist *L,ElemType n) { ElemType i,k=0;//k=0代表未找到该元素 for(i=0;i<L->length;i++) { if(n==L->elem[i]) { //元素在线性表中的位置为索引+1;可对比数组 printf("该元素出现在线性表的第%d个位置上\n",i+1); k=1; break; } } if(k==0) printf("未找到该元素\n"); }设置一个标志K=-1,先判断所查找元素n的值是否等于线性表的第一个元素,如果是,则令K=0;然后进入for循环,遍历第二个到最后一个元素,判断n是否与他们相等,如果是,令k=i,并输出;退出循环,此时判断k的值,k没有改变代表线性表中不存在这个元素,K=0代表n为线性表第一个元素,不存在前驱元素
void PriorElem(Sqlist *L,ElemType n) { ElemType i,k=-1;//k=-1代表未找到该元素 if(L->elem[0]==n) { k=0; }else { for(i=1;i<L->length;i++) { if(n==L->elem[i]) { printf("该元素的前驱元素是%d\n",L->elem[i-1]); k=i; break; } } } if(k==0) printf("该元素为顺序表第一个元素,不存在前驱\n"); else if(k==-1) printf("顺序表中不存在该元素\n"); }设置一个标志K=-1,先判断所查找元素n的值是否等于线性表的最后一个元素,如果是,则令K=0;然后进入for循环,遍历第一个直到倒数第二个元素,判断n是否与他们相等,如果是,令K=i,并输出;退出循环,此时判断k的值,k没有改变代表线性表中不存在这个元素,K=0代表n为线性表最后一个元素,不存在后继元素。
void NextElem(Sqlist *L,ElemType n) { ElemType i,k=-1;//k=-1代表未找到该元素 if(L->elem[L->length-1]==n) { k=0; }else { for(i=0;i<L->length-1;i++)//只有0~l->length-2上存在后继元素 { if(n==L->elem[i]) { printf("该元素的后继元素是%d\n",L->elem[i+1]); k=i; break; } } } if(k==0) printf("该元素为顺序表最后一个元素,不存在后继\n"); else if(k==-1) printf("顺序表中不存在该元素\n"); }首先判断插入位置是否合法,若不合法直接退出调用,并给出相应提示;然后判断该元素是否与线性表中的元素重复,若重复退出调用,并给出相应提示;接下来判断线性表存储空间是否足够;如果满了则为其增加新的内存空间;之后将插入位置之后的(包括插入位置的元素依次向后移一位),最后在要插入的位置插入元素(例如:插入位置如果是第一个,那么原先的第一个元素及其之后的就后退一位)
Status ListInsert(Sqlist *L,ElemType n,ElemType position) { ElemType i; ElemType * newbase; if(position<=0||position>L->length) { printf("插入位置不存在\n"); return ERROR; } for(i=0;i<L->length;i++) { if(n==L->elem[i]) { printf("该元素已存在,插入失败\n"); return ERROR; } } if(L->length>=L->listsize) {//相当于在原先的房子上又盖了几层 newbase=(ElemType *)realloc(L->elem,(L->listsize+LISTINCREMENT)*sizeof(ElemType)); if(!newbase) { printf("分配失败\n"); exit(OVERFLOW); } L->elem=newbase; L->listsize+=LISTINCREMENT; } for(i=L->length;i>=position;i--) {//未插入前最后一个位置是L.length-1;要插入的话就得向后移一位 L->elem[i]=L->elem[i-1]; } L->elem[position-1]=n; L->length++; printf("插入成功\n"); return OK; }首先判断删除位置是否合法,若不合法直接退出调用,并给出相应提示; 然后将所删除位置之后的元素(不包括所删除的位置)从前往后,依次向前移一位,最后将线性表的长度-1.
Status ListDelete(Sqlist * L,ElemType position) { ElemType i; if(position<=0||position>L->length) { printf("该位置不存在\n"); return ERROR; } for(i=position-1;i<L->length;i++) { L->elem[i]=L->elem[i+1]; } L->length--; printf("删除成功\n"); return OK; }主函数只负责调用函数,线性表的操作通过具体函数实现(其中,通过while语句和switch语句实现对于不同函数的调用,并通过if-else if语句实现对于用户输入数据异常的处理,在switch的分支中,通过设置标志k来判断线性表是否为空或者是否初始化)
int main() { ElemType i,k=0,x;//k表示顺序表的状态,k=0代表线性表未初始化 k=1代表初始化成功 ElemType position;//position用于接收用户输入的位置 ElemType L_length; //线性表长度 tips(); while(TRUE)//使用户可以进行持续的操作 { printf("请输入你的选择\n"); scanf("%d",&i); if(i<0) { printf("成功退出\n"); break; } else if(i>=1&&i<=12) { switch(i) { case 1://初始化线性表 k=InitList(&L); if(k==OK) printf("初始化线性表成功\n"); break; case 2://销毁线性表 if(!k) { printf("线性表为空或未初始化\n"); break; }else { k=DestroyList(&L); if(k==ERROR) printf("销毁成功\n"); else printf("销毁失败\n"); break; } case 3://清空线性表 if(!k) { printf("线性表为空或未初始化\n"); break; }else { k=ClearList(&L); if(k==ERROR) printf("线性表已清空\n"); else printf("清空线性表失败\n"); break; } case 4://判断线性表是否为空 if(!k) { printf("线性表未初始化\n"); break; }else { k=ListEmpty(&L); if(k==OK) printf("线性表不为空\n"); else printf("线性表为空\n"); break; } case 5://判断线性表的长度 if(!k) { printf("线性表为空或未初始化\n"); break; }else { L_length=ListLength(&L); break; } case 6://查找指定位置的元素 if(!k) { printf("线性表为空或未初始化\n"); break; }else { printf("请输入你所查找的位置\n"); scanf("%d",&position); GetElem(&L,position); break; } case 7://查找指定元素的位置 if(!k) { printf("线性表为空或未初始化\n"); break; }else { printf("请输入你所查找的元素\n"); scanf("%d",&x); LocateElem(&L,x); break; } case 8://查找指定元素的前驱元素 if(!k) { printf("线性表为空或未初始化\n"); break; }else { printf("请输入数字,将输出其前驱\n"); scanf("%d",&x); PriorElem(&L,x); break; } case 9://查找指定元素的后继元素 if(!k) { printf("线性表为空或未初始化\n"); break; }else { printf("请输入数字,将输出其后继\n"); scanf("%d",&x); NextElem(&L,x); break; } case 10://插入元素 if(!k) { printf("线性表为空或未初始化\n"); break; }else { printf("请输入所要插入的数字\n"); scanf("%d",&x); printf("请输入你所插入的位置\n"); scanf("%d",&position); ListInsert(&L,x,position); break; } case 11://删除指定位置的数字 if(!k) { printf("线性表为空或未初始化\n"); break; }else { printf("请输入所要删除的位置\n"); scanf("%d",&position); ListDelete(&L,position); break; } case 12://显示线性表 if(!k) { printf("线性表为空或未初始化\n"); break; }else { ListVisit(&L); break; } } }else { printf("输入错误\n");//遇见非数值时会出现死循环 } } return 0; }OK,本篇博客到此结束!江湖路远,有缘再见!