顺序表插入删除元素

顺序表

(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;  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值