顺序表的创建插入与删除

来源:互联网 发布:北京科技大学 网络咨询 编辑:程序博客网 时间:2024/04/27 20:00
顺序表的创建插入与删除
坑爹的数据结构课,在加上坑爹的数据结构老师,将来的数据结构之路想必不会顺畅吧敲打 。
好吧,闲话不多说。这该死的数据结构课上都没怎么听,哎我以为我“苦学”一寒假的链表,最开始的数据结构应该无压力吧,tmd没想到第二周的作业就让我懵逼了。
好吧一共三个题,第一个是处理矩阵,第二个是计算单词数,都是小菜一碟。但我看到第三题时:顺序表的创建,插入删除时,我傻眼了。嘛玩意儿!我就去开始翻教材——严蔚敏的《数据结构》。用一句话描述我当时的心情就是目瞪口呆。这他妈写的什么代码!排版之乱,还是用伪码写的。我虽然学编程不久,但我看无论是美国的《head first》系列还是日本的《征服c指针》,至少给出的代码是专门给了个区域工工整整的用及佳的代码风格写出来的啊。什么status,Elemtype,这是什么类型,我怎么没听说过啊!!!于是我上豆瓣看了一下次书的评论,果然是一片骂声啊。好在暑假自学的时候什么问题没遇到过啊。没怎么慌,于是上网搜索,然后又把书翻了一遍。哦,原来是要自己定义的。
我再一看老师给出的部分源码,要自己补充完整的。心里有事一万匹草泥马奔过。这些的什么啊!拜托变量声明写出来好吗,代码格式还能不能再乱一点。好吧经过我的刻苦攻关,代码写完了:
/*构造顺序表List(要求顺序表存储空间的初始分配长度为10,分配增量为5),在List上实现元素的插入、删除(提示:参照教材P23-24算法2.3,算法2.4,算法2.5)。具体要求如下:可以单独编写全部代码完成,也可以在如下代码里补充相应代码完成该实验任务。*/#include <stdio.h>#include <stdlib.h>#define LIST_INIT_SIZE 10 //线性表存储空间的初始分配量#define LISTINCREMENT 5   //线性表存储空间的分配增量#define TRUE 1#define OK 1#define FALSE 0#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2//请编码完成常量名及自定义数据类型的定义typedef int status;typedef int ElemType;typedef struct{    ElemType *elem;       //存储空间的基地址    int length;      //当前线性表的长度    int listsize;    //当前分配的存储容量}SqList;void InitList(SqList &l){    l.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));//动态申请初始内存    if(l.elem==NULL)    {        exit(OVERFLOW);    }    l.length=0;//长度初始化为零    l.listsize=LIST_INIT_SIZE;//初始化储存容量  //请编码完成顺序表l的初始化}status ListInsert(SqList &l,int i,ElemType e)//i为插入的位置,e为其值{    if (i<1 || i>l.length+1) return -1;    if(l.length>=l.listsize)    {        ElemType *newbase;        newbase=(ElemType *)realloc(l.elem,(l.listsize+LISTINCREMENT)*sizeof(ElemType));        if(newbase==NULL)        {            return -1;        }        l.elem=newbase;        l.listsize+=LISTINCREMENT;//扩大容量声明    }    ElemType *p,*q;    q=&l.elem[i-1];//下标减一    for(p=&(l.elem[l.length-1]);p>=q;--p)    {        *(p+1)=*p;    }//将i位置后的所有元素往后移一位    *q=e;    ++l.length;    return OK;}status ListDelete(SqList &l,int i,ElemType &e){    if(i>l.length||i<1)    {        return ERROR;    }    ElemType *p,*q;    p=&l.elem[i-1];    e=*p;//取得要删除的元素的地址    q=&l.elem[l.length-1];//取得最后一个元素、    while(p<q)    {        *p=*(p+1);         p++;    }    l.length--;    return 0;  //请编码完成删除顺序表l的第i个数据元素,并将删除元素值通过参数e返回。如果成功函数返回OK,否则返回ERROR。}int main(){SqList List;int e;int i,j;//初始化顺序表printf("************初始化顺序表********************\n");InitList(List);printf("初始化List后:List.length=%d  List.listsize=%d\n",List.length,List.listsize);//在表头依次插入1~10printf("\n**********在表头依次插入1~10***************\n");for (i=1;i<=10;i++)ListInsert(List,1,i);printf("在List的表头依次插入1~10后,表中的数据元素值为:");for (i=1;i<=List.length;i++)printf("%d  ",List.elem[i-1]);printf("\n");printf("List.length=%d  List.listsize=%d\n",List.length,List.listsize);//继续在表尾插入第11个元素值:11printf("\n*********继续在表尾插入第11个元素值:11*************\n");ListInsert(List,List.length+1,11);printf("在表尾插入11后,表中的数据元素值为:");for (i=1;i<=List.length;i++)printf("%d  ",List.elem[i-1]);printf("\n");printf("List.length=%d  List.listsize=%d\n",List.length,List.listsize);//依次删除表中第12,11个元素和第10个元素printf("\n************依次删除表中第12,11,10个元素*********\n");for (i=12;i>=10;i--){j=ListDelete(List,i,e);if (j==e)printf("删除第%d个元素失败\n",i);elseprintf("删除第%d个元素成功,其值为:%d\n",i,e);}printf("List.length=%d  List.listsize=%d\n",List.length,List.listsize);return 0;}
一开始我还以为顺序表就是链表,后来才发现不是,比链表要简单,他是在结构体里创建一个数组,两个int 变量分别记录数组长度,当前内寸大小。
插入的逻辑是这样的:
1.判断要插入的位置是否合法。(小于1或大于lenth)
2.判断数组长度有没有到内存容量极限,若容量满后应用realloc函数扩大。
3.定义两个指针,一个指向要插入的位置,一个指向最后一个。
4.从最后一个元素开始用*(p+1)=*p,依次移动。
5.将值赋给对应的位置。
6.lenth++.
删除的逻辑要简单点,但我当时犯了个毛病
for (i=12;i>=10;i--){j=ListDelete(List,i,e);if (j==e)printf("删除第%d个元素失败\n",i);elseprintf("删除第%d个元素成功,其值为:%d\n",i,e);}
这片代码,我当时纠结于e从哪里来,没有赋值啊。后来看到函数原型才知道,e是传地址进函数的,e在函数里赋值。
逻辑:
1.判断要插入的位置是否合法。
2.声明两个指针,一个指向删除元素的地址,一个指向末地址用来做结束循环的标志。
3.用将要被删除的值保存进e中
4.*p=*(p+1)
5.lenth--。
基本逻辑就是这样的。
0 0