顺序表
(1)分别建立4个元素的线性表L={2,3,4,5}:
(2)在L={2,3,4,5}的元素4与5之间插入-个元素9,实现表插入的基本操作;
(3)在L={2,3,4,9,5}中删除指定位置(i=3)上的元素,实现表删除的操作。
顺序表插入删除元素(点操作符法)
注意一:用malloc时要声明,引入stdlib.h以使用malloc和realloc
注意二:typedef int Status; //Status是变量的类型,其值是函数结果状态代码
注意三:Status InitList_Sq(SqList &L){ //注意用&L
ElemType *newbase, *q, *p;//注意声明以防出现[Error] 'newbase' was not declared in this scope
主函数中:ElemType e; //非常注意!这里是一个变量,不是指针
InitList_Sq(L); // 注意这里直接传递L,而不是&L,不是l的地址
if (ListDelete_Sq(L, 3, e)) {
//当前面 ListDelete_Sq引用参数时以&打头,除可提供输入值外,还将返回操作结果
//所以这里 L 和 e 不用加 &
#define ERROR 0
#define OK 1
#define OVERFLOW -2
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
#define LISTINCREMENT 10 //线性表存储空间的分配增量
#include <stdio.h>
#include <stdlib.h> //用malloc时要声明,引入stdlib.h以使用malloc和realloc
typedef int Status; //Status是变量的类型,其值是函数结果状态代码
typedef int ElemType; //定义ElemType数据元素类型
//线性表的动态分配顺序存储结构
typedef struct{
ElemType *elem; //存储空间基值
int length; //当前长度
int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList;
//构造一个空的线性表L,初始化顺序表
Status InitList_Sq(SqList &L){ //注意用&L
L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L.elem)exit(OVERFLOW); //存储分配失败
L.length=0; //空表长度为零
L.listsize=LIST_INIT_SIZE; //初始存储容量
return OK;
}//InitList_Sq
//插入元素,在顺序线性表L中第i个位置之前插入新的元素e
Status ListInsert_Sq(SqList &L,int i,ElemType e){
//i的合法值为1<=i<=ListLength_Sq(L)+1
ElemType *newbase, *q, *p;//注意声明以防出现[Error] 'newbase' was not declared in this scope
if(i<1||i>L.length+1)return ERROR; //i值不合法
if(L.length>=L.listsize){ //当前存储空间已满,增加分配
newbase=(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
if(!newbase)exit(OVERFLOW); //存储分配失败
L.elem=newbase; //新基址
L.listsize +=LISTINCREMENT; // 增加存储容量
}
q=&(L.elem[i-1]); //q为插入位置
for(p=&(L.elem[L.length-1]);p>=q;--p)
*(p+1)=*p; //插入位置及之后的位置右移
*q=e; //插入e
++L.length; //表中增1
} //ListInsert_Sq
//删除元素,在顺序线性表L中删除第i个元素,并用e返回其值
Status ListDelete_Sq(SqList &L,int i,ElemType &e){
//i的合法值为1<=i<=ListLength_Sq(L)
ElemType *p, *q;//在使用 p 和 q 指针之前,需要先声明它们。
if((i<1)||(i>L.length))return ERROR; //i值不合法
p=&(L.elem[i-1]); //p为被删除元素的位置
e=*p; //被删除元素的值赋给e
q=L.elem+L.length-1; //表尾元素的位置
for(++p;p<=q;++p)
*(p-1)=*p; //被删除元素之后的元素左移?
--L.length; //表长减1
return OK;
}//ListDelete_Sq
//打印顺序表,(注意:这里应该传递 SqList 的指针或复制整个结构,但复制可能不是最高效的)
void ListPrint(SqList L){
for (int i = 0; i < L.length; i++) {
printf("%d ", L.elem[i]);
}
printf("\n");
}
int main() {
SqList L;
ElemType e; //非常注意!这里是一个变量,不是指针
// 初始化顺序表
InitList_Sq(L); // 注意这里直接传递L,而不是&L ,不是l的地址
// 插入元素建立线性表L={2,3,4,5}
for (int i = 1; i <= 4; i++) {
ListInsert_Sq(L, i, i + 1); // 同样,直接传递L
}
// 打印线性表L
printf("线性表L={");
ListPrint(L);
// 在L={2,3,4,5}的元素4与5之间插入一个元素9
ListInsert_Sq(L, 5, 9); // 注意索引应该是5,因为在最后一个元素之后插入
// 打印插入后的线性表L
printf("插入9后,线性表L=");
ListPrint(L);
// 在L={2,3,4,9,5}中删除指定位置(i=3)上的元素
if (ListDelete_Sq(L, 3, e)) {
//当前面 ListDelete_Sq引用参数时以&打头,除可提供输入值外,还将返回操作结果
//所以这里 L 和 e 不用加 &
printf("删除位置i=3的元素,其值为%d\n", e); //删除位置i从1,2,3数起
} else {
printf("删除失败\n");
}
// 打印删除后的线性表L
printf("删除后,线性表L={");
ListPrint(L);
return 0;
}
顺序表插入删除元素(指针法)
注意一:Status ListInsert_Sq(SqList *L,int i,ElemType e)
ListInsert_Sq 和 ListDelete_Sq 函数的参数应该是指向 SqList 的指针,而不是引用;
c语言本身不支持传递(c++支持),因此在c语言环境下,需要将SqList &L修改为SqList *L并在调用时传递指向列表的指针;
在函数内部,需要使用 (*L).elem、(*L).length 等来访问列表成员
注意二:Status ListDelete_Sq(SqList *L,int i,ElemType *e)
用 ElemType *e以使用指针来接收被删除元素的值, 下面用 *e=*p;
用 ElemType &e参数时下面用 e=*p ;
注意三:
在 main 函数中,调用这些函数时都传递了 &L,即 L 的地址;
InitList_Sq、ListInsert_Sq 和 ListDelete_Sq 函数的参数都更改为 SqList *L,以接受指向 SqList 的指针;
ListDelete_Sq 函数的 ElemType &e 参数更改为 ElemType *e,以匹配 C 语言的指针传递;
注意四: if (ListDelete_Sq(&L, 3, &e))
ListDelete_Sq里用ElemType *e时这里要用&e,若用ElemType &e时这里用e
#define ERROR 0
#define OK 1
#define OVERFLOW -2
#define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量
#define LISTINCREMENT 10 //线性表存储空间的分配增量
#include <stdio.h>
#include <stdlib.h> //引入stdlib.h以使用malloc和realloc
typedef int ElemType; //定义ElemType为数据元素类型
typedef int Status; //Status是变量的类型,其值是函数结果状态代码
//线性表的动态分配顺序存储结构
typedef struct{
ElemType *elem; //存储空间基值
int length; //当前长度
int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList;
//构造一个空的线性表L,初始化顺序表
Status InitList_Sq(SqList *L){ //注意这里用指针传递
L->elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L->elem)exit(OVERFLOW); //存储分配失败
L->length=0; //空表长度为零
L->listsize=LIST_INIT_SIZE; //初始存储容量
return OK;
}//InitList_Sq
//插入元素,在顺序线性表L中第i个位置之前插入新的元素e
Status ListInsert_Sq(SqList *L,int i,ElemType e){ //
//i的合法值为1<=i<=ListLength_Sq(L)+1
//ListInsert_Sq 和 ListDelete_Sq 函数的参数应该是指向 SqList 的指针,而不是引用
//c语言本身不支持传递(c++支持),因此在c语言环境下,需要将SqList &L修改为SqList *L并在调用时传递指向列表的指针
//在函数内部,需要使用 (*L).elem、(*L).length 等来访问列表成员
ElemType *newbase, *q, *p; //注意声明以防出现[Error] 'newbase' was not declared in this scope
if(i<1||i>L->length+1)return ERROR; //i值不合法
if(L->length>=L->listsize){ //当前存储空间已满,增加分配
newbase=(ElemType *)realloc(L->elem,(L->listsize+LISTINCREMENT)*sizeof(ElemType));
if(!newbase)exit(OVERFLOW); //存储分配失败
L->elem=newbase; //新基址
L->listsize +=LISTINCREMENT; //增加存储容量
}
q=&(L->elem[i-1]); //q为插入位置
for(p=&(L->elem[L->length-1]);p>=q;--p)
*(p+1)=*p; //插入位置及之后的位置右移
*q=e; //插入e
++L->length; //表长增1
} //ListInsert_Sq
//删除元素,在顺序线性表L中删除第i个元素,并用e返回其值
Status ListDelete_Sq(SqList *L,int i,ElemType *e){
//用 ElemType *e以使用指针来接收被删除元素的值, 下面用 *e=*p
//用 ElemType &e参数时下面用 e=*p
//i的合法值为1<=i<=ListLength_Sq(L)
ElemType *newbase, *q, *p;
if((i<1)||(i>L->length))return ERROR; //i值不合法
p=&(L->elem[i-1]); // p为被删除元素的位置
*e=*p; //被删除元素的值赋给e //用指针来接受值
q=L->elem+L->length-1; //表尾元素的位置
for(++p;p<=q;++p)
*(p-1)=*p; //被删除元素之后的元素左移
--L->length; //表长减1
return OK;
}//ListDelete_Sq
//打印顺序表,(注意:这里应该传递 SqList 的指针或复制整个结构,但复制可能不是最高效的)
void ListPrint(SqList L){
// 注意:这里传递的是整个结构体的副本,如果 SqList 很大,这可能会很昂贵
// 更好的做法是通过指针传递
for (int i = 0; i < L.length; i++) {
printf("%d ", L.elem[i]);
}
printf("\n");
}
int main() {
//在 main 函数中,调用这些函数时都传递了 &L,即 L 的地址
//InitList_Sq、ListInsert_Sq 和 ListDelete_Sq 函数的参数都更改为 SqList *L,以接受指向 SqList 的指针
//ListDelete_Sq 函数的 ElemType &e 参数更改为 ElemType *e,以匹配 C 语言的指针传递
SqList L;
ElemType e;
// 初始化顺序表
InitList_Sq(&L); //注意这里需要传递L的地址
// 插入元素建立线性表L={2,3,4,5}
for (int i = 1; i <= 4; i++) {
ListInsert_Sq(&L, i, i + 1);
}
// 打印线性表L
printf("线性表L={");
ListPrint(L);
// 在L={2,3,4,5}的元素4与5之间插入一个元素9
ListInsert_Sq(&L, 4, 9);
// 打印插入后的线性表L
printf("插入9后,线性表L={");
ListPrint(L);
// 在L={2,3,4,9,5}中删除指定位置(i=3)上的元素
if (ListDelete_Sq(&L, 3, &e)) {
//ListDelete_Sq里用ElemType *e时这里要用&e,若用ElemType &e时这里用e
printf("删除位置i=3的元素,其值为%d\n", e); //删除位置i从1,2,3数起
} else {
printf("删除失败\n");
}
// 打印删除后的线性表L
printf("删除后,线性表L={");
ListPrint(L);
return 0;
}