一、简单描述
思路:设存储元素ai的结点为q,要实现将结点q删除单链表的操作其实就是将它的前继结点的指针绕过指向它的后继结点即可。
结果:删除L的第i个元素,用e返回其值,链表长度减一
(图源:程杰《大话数据结构(溢彩加强版)》)
核心算法:
1.q=p->next; //q作为临时指针,将p的后继也就是ai赋值给q
2.p->next=q->next; //再将q的后继也就是ai+1赋值给p的后继也就是ai
二、详细步骤:
1.初始化指针和计数器
j初始化为1,用于记录当前遍历的节点位置
定义两个指针变量p和q,其中p
指向链表的头节点,q用于要删除的节点。
int j=1;
LinkList p,q;
p=*L;
2.遍历链表找到第i个位置节点
使用while循环,直到找到第i个位置或链表末尾
while(p->next&&j<i){
p=p->next;
++j;
}
3.判断插入位置是否合理
如果找到第i个结点或i=链表长度加1,证明插入合理
如果未找到第i个节点(则p=NULL)或i小于1,则插入不合理,返回错误信息
if(!p->next||i<1){
return ERROR;
}
4.执行删除操作
q=p->next; //将p的后继赋值给q
p->next=q->next; //将q的后继赋值给p的后继
*e=q->data; //用e返回被删除结点q的数据
free(q); //释放q的内存空间
5.返回操作结果
return OK;
三、核心代码:
int ListInsert(LinkList *L,int i,ElemType e)
{
int j=1;
LinkList p,s;
p=*L;
while (p->next&& j<i) /*寻找第 i 个节点*/
{
p=p->next;
++j;
}
if (!p->next || j>i)
return ERROR; /*第 i 个元素不存在*/
q = p->next;
p->next = q->next;
*e = q->data;
free(q);
return OK;
}
四、完整代码:
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct Node {
ElemType data;
struct Node* next;
} Node;
typedef Node* LinkList;
typedef int Status;
#define OK 1
#define ERROR 0
/* 删除链表中第i个元素,并用e返回其值 */
Status ListDelete(LinkList *L, int i, ElemType *e) {
int j;
LinkList p, q;
p = *L;
j = 1;
/* 遍历寻找第i个元素 */
while (p->next && j < i) {
p = p->next;
++j;
}
/* 第i个元素不存在 */
if (!(p->next) || j > i) {
return ERROR;
}
q = p->next;
p->next = q->next;
*e = q->data;
free(q);
return OK;
}
/* 初始化链表 */
void InitList(LinkList *L) {
*L = (LinkList)malloc(sizeof(Node));
if (!(*L)) {
exit(EXIT_FAILURE); // 内存分配失败,程序退出
}
(*L)->next = NULL;
}
/* 打印链表元素 */
void PrintList(LinkList L) {
LinkList p = L->next;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
/* 释放链表内存 */
void DestroyList(LinkList *L) {
LinkList p = (*L)->next;
while (p) {
LinkList temp = p;
p = p->next;
free(temp);
}
free(*L);
*L = NULL;
}
int main() {
LinkList list;
ElemType deletedElement;
/* 初始化链表并插入一些元素 */
InitList(&list);
for (int i = 1; i <= 5; ++i) {
LinkList newNode = (LinkList)malloc(sizeof(Node));
if (!newNode) {
exit(EXIT_FAILURE);
}
newNode->data = i * 10;
newNode->next = list->next;
list->next = newNode;
}
printf("原始链表: ");
PrintList(list);
int deletePosition = 3;
Status result = ListDelete(&list, deletePosition, &deletedElement);
if (result == OK) {
printf("删除第%d个元素后的链表: ", deletePosition);
PrintList(list);
printf("被删除的元素值为: %d\n", deletedElement);
} else {
printf("删除失败,第%d个元素不存在或操作异常。\n", deletePosition);
}
/* 释放链表内存 */
DestroyList(&list);
return 0;
}