单链表插入删除元素

单链表,实验内容

(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)上的元素,实现表删除的操作。

常见错误:

  1. 类型定义错误 :应该使用 LinkList 类型,它是链表定义的类型。

  2. 变量未声明 :在 ListInsert_LListDelete_L 函数中,使用 js 变量要声明。

  3. 函数参数类型不匹配ListPrint 函数的参数应该是 LinkList 而不是 LinkList &,因为不需要修改传入的链表头指针。

  4. 引用传递问题 :在 main 函数中,应该首先创建一个链表的头节点,并将其 next 指针设置为 NULL

  5. ElemType 传递方式 :在 GetElem_L 函数中,不能使用 ElemType &e,这在 C 语言中是不合法的。C 语言不支持引用传递,应该使用指针。

  6. 代码风格 :在 C 语言中,通常不使用 & 符号来引用结构体成员,除非是在定义结构体指针。

调试遇到的问题及分析解决方法

  1. 问题 :在 GetElem_L 函数中,循环条件 while(p&&j<1) 永远不会执行,因为 j 初始化为 1,而条件是 j<1
    • 解决方法 :将循环条件改为 while(p && j < i),确保在找到第 i 个元素之前循环继续执行。
  2. 问题 :在 ListInsert_L 函数中,当 i 等于链表长度加 1 时,应该能够成功插入新元素到链表末尾,但原代码中的 if(!p||j>i-1) 阻止了这种情况。
    • 解决方法 :将条件改为 if(!p || j != i-1),这样当 p 为空或 j 不等于 i-1 时才返回错误。
  3. 问题 :在 ListDelete_L 函数中,当 i 等于链表长度时,应该返回错误,因为不存在第 i 个元素。但原代码中的条件 if(!(p->next)||j>i-1) 允许 i 等于链表长度时执行删除操作(尽管实际上不会删除任何元素,因为 p->next 为空)。
    • 解决方法 :虽然这个特定情况可能不会导致错误(因为 p->next 为空时不会执行删除操作),但为了代码的清晰性和一致性,可以保留这个条件检查,或者更明确地处理这种情况。
  4. 问题 :在 main 函数中,插入元素时索引从 1 开始,但链表长度是 0(因为只有一个头结点且其 next 为空),所以第一个元素应该插入到位置 1 而不是 0。
    • 解决方法 :这个问题实际上在代码中已经正确处理了,因为插入函数 ListInsert_L 的索引是从 1 开始的。
  5. 代码风格 :使用 ElemType &e 作为函数参数时,需要注意在函数内部直接通过 e 赋值,而在调用时不需要额外的 & 符号(除非是在需要指针的场景下)。
    • 解决方法 :在 ListDelete_LGetElem_L 函数中,使用 ElemType &e 是正确的,因为这样可以避免不必要的内存分配和复制操作。在调用这些函数时,直接传递变量名即可。
cs 复制代码
#define ERROR 0
#define OK 1
#define OVERFLOW -2

#include <stdio.h>   
#include <stdlib.h> //引入stdlib.h以使用malloc和realloc 

typedef int ElemType;  //定义ElemType为数据元素类型 
typedef int Status; //Status是变量的类型,其值是函数结果状态代码 

typedef struct LNode{
	ElemType data; //结点值 
	struct LNode *next; //连接下一个结点的地址 
}LNode,*LinkList; //数据域,指针域 

Status GetElem_L(LinkList L,int i,ElemType &e){
//这里用ElemType &e则下面用 e=p->data;若为*e则下面也要*e 
	//L为带头结点的单链表的头指针 
	//当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR 
	LNode *p=L->next; 
	int j=1; //初始化,p指向第一个结点,j为计数器 
	while(p&&j<i){ //顺时针向后查找,直到p指向第i个元素或p为空 
		p=p->next; 
		++j;
	}
	if(!p||j>1)return ERROR; //第i个元素不存在 
    e=p->data; //取第i个元素 
    return OK;
}//GetElem_L

Status ListInsert_L(LinkList *L,int i,ElemType e){
    //存疑,这里用 LinkList *L,则下面用LNode *p=*L而非p=L ,同时定义*s 
	//在带头结点的单链线性表L中第i个位置之前插入元素e 
	LNode *p=*L,*s;
	int j=0;
	while(p&&j<i-1){ 
    	p=p->next;
    	++j;	
		} //寻找第i-1个结点 
	if(!p||j>i-1)return ERROR; //i<1或者大于表长+1 
	s=(LinkList)malloc(sizeof(LNode)); //生成新节点 
	s->data=e;
	s->next=p->next; //插入L中 
	p->next=s;
	return OK;
}//ListInsert_L

Status ListDelete_L(LinkList *L,int i,ElemType &e){ //同上 
	//在带头结点的单链线性表L中,删除第i个元素,并由e返回其值 
	LNode *p=*L,*q;
	int j=0;
	while(p->next&&j<i-1){ //寻找第i个结点,并令p指向其前驱 
		p=p->next;++j;
	}
	if(!(p->next)||j>i-1)return ERROR; //删除位置不合理 
	q=p->next; 
	p->next=q->next; //删除并释放结点 
	e=q->data; free(q);
	return OK;
}//ListDelete_L

void ListPrint(LinkList L){
	LNode *temp=L->next; //从头结点的下一个结点开始打印 
	while(temp!=NULL){
		printf("%d ",temp->data);
		temp=temp->next;
	} 
    printf("\n");
}

int main() {  
    LinkList L=(LinkList)malloc(sizeof(LNode)); //创建头结点
	if(!L) return -1; //内存分配失败
	L->next=NULL; //初始化头结点的next指针 
	
    ElemType e;  
  
    // 插入元素建立线性表L={2,3,4,5}  
    for (int i = 1; i <= 4; i++) {  
        ListInsert_L(&L, i, i + 1);  
    }  
  
    // 打印线性表L  
    printf("线性表L={");  
    ListPrint(L);  
  
    // 在L={2,3,4,5}的元素4与5之间插入一个元素9  
    ListInsert_L(&L, 4, 9);  
  
    // 打印插入后的线性表L  
    printf("插入9后,线性表L={");  
    ListPrint(L);  
  
    // 在L={2,3,4,9,5}中删除指定位置(i=3)上的元素  
    if (ListDelete_L(&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;  
}
相关推荐
羊小猪~~3 分钟前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
洋24023 分钟前
C语言常用标准库函数
c语言·开发语言
王哈哈^_^28 分钟前
【数据集】【YOLO】【VOC】目标检测数据集,查找数据集,yolo目标检测算法详细实战训练步骤!
人工智能·深度学习·算法·yolo·目标检测·计算机视觉·pyqt
星沁城30 分钟前
240. 搜索二维矩阵 II
java·线性代数·算法·leetcode·矩阵
脉牛杂德1 小时前
多项式加法——C语言
数据结构·c++·算法
legend_jz1 小时前
STL--哈希
c++·算法·哈希算法
徐嵌1 小时前
STM32项目---畜牧定位器
c语言·stm32·单片机·物联网·iot
kingmax542120081 小时前
初三数学,最优解问题
算法
一直学习永不止步1 小时前
LeetCode题练习与总结:赎金信--383
java·数据结构·算法·leetcode·字符串·哈希表·计数
小刘|2 小时前
《Java 实现希尔排序:原理剖析与代码详解》
java·算法·排序算法