一、顺序表
- 因为系统没直接给提供数据结构,所以需要先定义对应数据结构的结构体
- 有了结构体,需要初始化该数据结构
- 初始化完毕,然后可以定义自己需要的操作
二、代码解释
1.初始化
void list_init(List *L) //初始化
{
L->elem=(Elemtype *)malloc(MAXSIZE*sizeof(Elemtype));//开辟空间
if(L->elem==NULL)//判断空间是否开辟成功
{
printf("malloc fail\n");
exit(0);
}
L->len=0; //初始化数据有效数据为0
L->listsize=MAXSIZE; //初始化数组长度为MAXSIZE
}
代码中
L->elem=(Elemtype *)malloc(MAXSIZE*sizeof(Elemtype));
L指针 指向elem,
这样申请了一个由L指针所指的、类型为ElemType,长度为MAXSIZE的动态数组
下图为空间申请函数申请一个结点空间,malloc为系统内存分配函数。
2.插入(这个为了学习,找了几个好理解的)
在顺序表L的第p(0<=p<=length)个位置插入新的元素e。如果p的输入不正确,则返回0,代表插入失败。
如果p的输入正确,则将顺序表第p个元素及以后元素后移一个位置,空出一个空位置插入新元素。
顺序表长度加1,插入操作成功,返回1
int insert(Sqlist &L,int p,int e)
{
int i;
if(p<0||L.length||L.length==maxSize)//位置错误或者等于表长
return 0;//顺序表的最大允许值,此时插入不成功,返回0
for(i=L.length-1;i>=p;-i)
L.data[i+1]=L.data[i]; //从后往前,逐个将元素往后移动一位
L.data[p]=e; //将e放在插入位置p上
++(L.length); //表内元素多了一个,所表长增1
return 1; //插入成功返回1
}
顺序表插入
int insert(Sqlist &L,int i,DataType &x){
//将新元素插入表中第i(1<=i<=n+1)个位置。若插入成功函数返回1,否则返回0
if(L.n==L.maxSize) //表满不能插入
return 0;
if(i<0||i>L.n+1) //位置参数i不合理 不能插入
return 0;
for(int j=L.n;j>=i;j--)//依次后移,空出第i个位置
L.data[j]=L.data[j-1];
L.data[i-1]=x; //插入
L.n++; /表长加1
return 1; //插入成功
}
总结要在第i个位置插,
先看能不能插,
不能插,退出。
能插,把i后的元素每个后移一个位置,
然后把新的东西插入。
用大白话说,要给原来的顺序表某个位置插入东西,
首先得看看 这个位置合理不,
比如顺序表满了,或者这个位置超出表的长度。
(比如这个屋子最多放8个桌子(假设就只有一列挨着放),现在放了7个桌子,
你说你要在第五个位置放个桌子,先看看这屋子还能再放下桌子吗,这个位置合理不。
此时屋子还能放一个桌子,你可以放。但是你说要再第20个位置放入桌子这就不行了)
插入前
a | b | c | d | e | f | g |
|
再第五个位置插入H,插入后
a | b | c | d | H | e | f | g |
3.删除(一切为了理解)
顺序表删除,按位置删除
int Remove(SeqList &L,int i,DataType &x){
//删除顺序表第i(1<=i<=n)个元素,通过引用型参数x返回删除元素的值。
//若删除成功则返回1,否则返回0
if(!L.n) //表空,不可删除
return 0;
if(i<1||i>L.n) return 0; //参数i不合理,不能删除
x=L.data[i-1]; //存储被删元素的值
for(int j=i;j<L.n;j++) //依次前移
L.data[j-1]=L.data[];
L.n--; //表长度减1
return 1; //删除成功
}
删除顺序表L中下标为p(0<=p<=length)的元素,成功返回1,否则返回0,并将被删除元素的值赋给e。
int DeleeteElem(Sqlist &L,int p,int &e)//需要改变的变量用引用型号
{
int i;
if(p<0||p<L.length-1)
return 0; //位置不对返回0代表删除不成功
e=L.data[p]; //将被删除的元素赋值给e
for(i=p;i<L.length-1;i++) //从p的位置开始,将其后边的元素诸葛前移一个位置
L.data[i]=L.data[i+1];
--(L.length); //表长减1
return 1; //删除成功,返回1
}
人话讲解,
你想删除第i个位置的元素,先看看表中有东西吗,空空如也肯定没法删除
再这个位置i合理不,下面总共有8个位置,删除第5个可以,但删除第9个不可以。
a | b | c | d | H | e | f |
|
删除第五个H,先用个东西把H存进去,然后把e和f往前挪一个位置
删除后
a | b | c | d | e | f |
|
|
删除总结,先看能删不,不能删退出,能删将第i个位置之后的元素往前挪一个 。
//这个代码来自https://blog.csdn.net/qq_34991245/article/details/82695372
//这代码略有瑕疵,运行会报异常,不过不影响学习
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
#define MAXSIZE 10
#define OK 1
#define FALSE 0
//顺序表的动态结构
typedef int Elemtype;
typedef bool Status;
typedef struct list//定义结构体
{
Elemtype *elem;//存储数组
int len; //当前表元素个数
int listsize; //表的最大长度
}List;
void list_init(List *L) //初始化
{
L->elem=(Elemtype *)malloc(MAXSIZE*sizeof(Elemtype));//开辟空间
if(L->elem==NULL)//判断空间是否开辟成功
{
printf("malloc fail\n");
exit(0);
}
L->len=0; //初始化数据有效数据为0
L->listsize=MAXSIZE; //初始化数组长度为MAXSIZE
}
Status list_insert(List *L,int i,Elemtype data) //插入
{
Elemtype *base,*insert,*p;
if(i<1 || i>L->len+1 || L==NULL)
{
printf("位置输入错误\n");
return FALSE;
}
if(L->len > L->listsize)
{
base=(Elemtype *)realloc(L->elem,(L->listsize+MAXSIZE)*sizeof(Elemtype));
L->elem=base;
L->listsize+=MAXSIZE;
}
insert=&(L->elem[i-1]);//目标指针指向要插入的目标地址
//指向最后一个元素的地址
for(p=L->elem + L->len-1;p>=insert;p--)
{
*(p+1)=*p;
}
*insert=data;
L->len++;
return OK;
}
Status list_delete(List *L,int i)
{
Elemtype *aim,*p;
if(i<0 || i>L->len)
{
printf("位置输入错误\n");
return FALSE;
}
aim=&(L->elem[i-1]);//目标指针指向要删除的目标地址
p=(L->elem+L->len-1); //指向最后一个元素的地址
for(aim=aim+1;aim<=p;++aim) //目标地址滑动删除
{
*(aim-1)=*aim;
}
L->len--;
return OK;
}
void show_list(List *L)
{
int i;
for(i=0;i<L->len;i++)
{
printf("elem[%d]=%d\n",i+1,L->elem[i]);
}
printf("\n");
}
int main()
{
int i;
List L;
list_init(&L);
for(i=0;i<10;i++)
{
list_insert(&L,i+1,i+1);
}
printf("插入前的顺序表\n");
show_list(&L);
printf("插入后的顺序表 在5位置插入99\n");
list_insert(&L,5,99);
show_list(&L);
printf("删除后的顺序表 把5位置删除\n");
list_delete(&L,5);
show_list(&L);
return 0;
}