线性表的插入和删除
转自:https://www.cnblogs.com/tqdlb/p/11632031.html
线性表其实跟数组差不多,但多了一个指针的传递
我们先来看看线性表的定义:
typedef struct {
int *elem;
int length; //这里我们定义了线性表的长度,也就是元素的个数了//
int listsize; //这个就是我们线性表的存储容量了//
}Sqlist;
这样就定义完了,是不是很OK,接下来我们看看怎么创建线性表
1.创建函数
int Initlist_Sq(Sqlist *L){
L->elem=(int *)malloc(LIST_INIT_SIZE*sizeof(int)); //分配存储空间,malloc函数用来分配,elem用来保存我们分配的空间的地址//
if(!L->elem) exit(ERROR); //还没懂ing//
L->length=0; //初始线性表的长度设为0//
L->listsize=LIST_INIT_SIZE; //这个list什么size是我们一开始就define(宏定义)的一个值哦//
return OK;
}
一个分配空间函数,几个赋值,一个简单的线性表就被创造出来啦
2.插入函数
进入我们的第一个功能函数,插入
大家想一想数组的内容,a[0],a[1].......数组就是通过这样来保存值的,那我们要插入一个怎么办
没错,就是用中间变量,用中间变量来保存插入那个位置的量如何通过一个for或者while循环我们就可以把值传递下去了
这样我们就在线性表的中间插入了一个值
int ListInsert_Sq(Sqlist *L,int i,int e){
if(i<1||i>L->length+1) return ERROR; //如果我们输入插入的位置大于线性表的长度怎么办,一个if帮你解决//
int *newbase,*q,*p;
if(L->length>=L->listsize){ //这个if就是用来判断我们现在拥有的空间是不是足够再插入进一个元素,不够的话我们就需要再分配一下了//
newbase=(int *)realloc(L->elem,(L->listsize+LISTINCREMENT)*sizeof(int));
if(!newbase) exit(ERROR);
L->elem=newbase; //我们把新开辟的空间地址传递一下//
L->listsize+=LISTINCREMENT; //这个就是用来增加我们拥有的空间的了//
}
q=&(L->elem[i-1]); //我们上面提到的中间变量哦//
for(p=&(L->elem[L->length-1]);p>=q;--p) *(p+1)=*p; //for循环把后面的值
*q=e;
++L->length; //这里我只能说,没用,因为要用到指针传递,不然这个长度好像就没用传递回去,我依旧又用了外部变量,大家有更好解决方案或者对指针熟悉的可以在评论区里告诉我哦
return OK;
}
3.删除函数
删除删除删除,大家想一下,线性表怎么删除呢?
还是拿数组来作对比,想删除一个中间的东西,其实就是把后面的元素覆盖到前面来,占据那个你想删除的位置
int ListDelete_Sq(Sqlist *L,int i){
if(i<1||(i>L->length)) return ERROR; //已经是第4个了吧,判断输入的位置//
int *p,*q,e;
p=&(L->elem[i-1]); //把删除的位置告诉p,注意是i-1哦,因为线性表是从0开始的哦//
e=*p; //留作纪念的e//
q=L->elem+L->length-1; //怎么突然冒出来一个q呢,大家想一想,我们要把后面的元素全部往前移,那怎么判断到底了呢,这里就设置了一个 q,作为结束的标志//
for(++p;p<=q;++p) *(p-1)=*p; //这个就是用来覆盖的啦//
return OK;
}
4.主函数
好了,总于到了主函数了,不容易,坚持一下,马上就完了
void main()
{
Sqlist L; //定义一个线性表//
int i,len,e,a,b;
Initlist_Sq(&L); //创建线性表//
printf("请输入线性表的长度: ");
scanf("%d",&len);
L.length=len;
printf("请输入线性表的元素: ");
for(i=0;i<len;i++){
scanf("%d",L.elem+i);
L.listsize--; //每输入一个元素,存储空间也就会相对的减少//
}
printf("\n请选择 1,插入 2,不插入 :");
scanf("%d",&a);
if(a==1){
printf("请输入要插入的元素: ");
scanf("%d",&e);
printf("请输入要插入的位置: ");
scanf("%d",&i);
ListInsert_Sq(&L,i,e);
printf("插入后的线性表为\n");
for(i=0;i<len+1;i++){ //大家还记得我在上面说到过的长度返回不了吧,因为只插入一次,所以我们就直接+1了,有点投机取巧,哎//
printf("%d ",L.elem[i]); //看这个输出元素,是不是真的跟数组差不多呀,是不是//
}
}
else
a=0; //为什么冒出来一个a=0呢,后面就知道啦//
printf("\n请选择 1,删除 2,不删除 :");
scanf("%d",&b);
if(b==1)
{
printf("请输入要删除元素的位置: ");
scanf("%d",&i);
ListDelete_Sq(&L,i);
printf("删除后的线性表为\n");
for(i=0;i<len+a-1;i++){ //同样是长度不能返回,为什么这里不一样呢,因为删除首先就要-1,但是我们还要判断之前是不是进行了插入操作,所以 就用到a啦//
printf("%d ",L.elem[i]);
}
}
}
ok,单链表就到这里了,其实对于这种简单的插入和删除操作,我们可以试着加入更多操作,像菜单界面啊,文件保存和打开啊,大家加油!!!
有不对的希望大家帮忙指出来哦!!
附C语言式列:
#include <stdio.h>
#include <stdlib.h>
#define LIST_INIT_SIZE 5 //线性表初始长度
#define LISTINCREMENT 5 //线性表每次扩充长度
#define OK 1
#define ERROR 0
//线性表结构体
typedef struct SqList{
int *elem;
int len;
int size;
};
//初始化线性表
int InitList_Sq(struct SqList *L){
//使用malloc函数,申请一段连续的存储空间
L->elem = (int *)malloc(LIST_INIT_SIZE * sizeof(int));
if(!L->elem)exit(0);
L->len=0;
L->size = LIST_INIT_SIZE;
return OK;
}
//向线性表中插入数据
int ListInsert_Sq(struct SqList *L,int i,int e){
if(i<1||i>L->len+1) return ERROR;
if(L->len>=L->size){
//使用realloc函数,在原本的基地址上申请更大的存储空间
int *newbase = (int *)realloc(L->elem,(LIST_INIT_SIZE + LISTINCREMENT) * sizeof(int));
//如果申请空间失败则结束程序
if(!newbase)exit(0);
L->size += LISTINCREMENT;
}
int *q = &(L->elem[i-1]);
int *p;
for(p=&L->elem[L->len-1];p>=q;--p)
*(p+1)=*p;
*q=e;
++L->len;
return OK;
}
//删除线性表中的数据
int ListDelete_Sq(struct SqList *L,int i,int *e){
if(i<1||i>L->len) return ERROR;
int *p=&(L->elem[i-1]);
*e=*p;
int q= L->elem + L->len-1;
for(++p;p<=q;++p)
*(p-1)=*p;
L->len--;
return OK;
}
//输出线性表中的数据
int ListShow_Sq(struct SqList *L,char* s){
printf("%s",s);
int i;
for(i=0;i<L->len;i++){
printf("%d ",L->elem[i]);
}
putchar('\n');
}
void main(){
int i;
struct SqList L;
//初始化线性表
InitList_Sq(&L);
//输入数据
int n;
printf("预先输入的原始数据个数是:");
scanf("%d",&n);
printf("请线性表中%d个原始数据:",n);
for(i=0;i<n;i++){
int t;
scanf("%d",&t);
ListInsert_Sq(&L,L.len+1,t);
}
ListShow_Sq(&L,"原始数据:");
//定义插入/删除操作时位置和数值参数
int s,v;
//插入操作
printf("请输入数据插入的位置s 和数值v :");
scanf("%d%d",&s,&v);
printf("%s",ListInsert_Sq(&L,s,v)?"插入成功.\n":"插入失败.\n");
ListShow_Sq(&L,"插入后:");
//删除操作
printf("请输入数据删除的位置s :");
scanf("%d",&s);
if(ListDelete_Sq(&L,s,&v))
printf("删除成功.删除的数据是:%d\n",v);
else
printf("删除失败.位置有误.");
ListShow_Sq(&L,"删除后:");
system("pause");
}