设计一个算法:删除非空单链表L中结点值为x的第一个结点的前驱结点
目录
单链表的存储结构定义如下
快慢指针法
三指针法版本①
三指针法版本②
单链表的存储结构定义如下
typedef struct{Elemtype data;struct Node* next;
}LNode,*LinkList;
快慢指针法
void deleteprex(LinkList L, Elemtype e) {if (L == NULL || L->next == NULL || L->next->next == NULL) {return; // 链表为空、只有一个节点或两个节点,无法删除前驱节点}LinkList q = L; // 慢指针,指向当前节点的前驱LinkList p = L->next; // 快指针,用于查找值为e的节点// 检查第一个数据节点是否是目标节点(此时没有前驱节点)if (p->data == e) {return; // 无法删除前驱节点,直接返回}// 从第二个数据节点开始遍历p = p->next; // p指向第二个数据节点while (p != NULL) {if (p->data == e) {// 找到值为e的节点,删除其前驱节点(即q的下一个节点)LinkList temp = q->next;q->next = p;free(temp);return; // 只删除第一个出现的节点的前驱,处理完后立即返回}// 未找到,指针后移q = q->next;p = p->next;}
}
三指针法版本①
int DelNodeX_L(LinkList &L, ElemType x) {// 初始化指针:prepre 指向头结点,pre 指向第二个结点,p 待初始化LinkList prepre = L, pre = prepre->next, p; // 若第二个结点值就是 x,无有效前驱可删,返回失败if (pre->data == x) return 0; // p 指向第三个结点,开始遍历找值为 x 的结点p = pre->next; while (p != NULL && p->data != x) { // 指针后移:prepre → pre → pprepre = pre; pre = p; p = p->next; } // 找到值为 x 的结点(p 非空),删除其前驱(pre)if (p != NULL) { // prepre 跳过 pre,直接指向 pprepre->next = p; // 释放前驱结点内存free(pre); // 返回删除成功return 1; } else { // 未找到值为 x 的结点,返回失败return 0; }
}
三指针法版本②
void deleteprex(LinkList L, Elemtype e) {if (L == NULL || L->next == NULL || L->next->next == NULL) {return; // 链表为空、只有一个节点或两个节点,不可能存在前驱节点}LinkList pre = L; // 前驱节点的前驱(用于删除操作)LinkList cur = L->next; // 当前节点,用于查找值为e的节点// 检查第一个数据节点是否是目标节点(此时没有前驱节点)if (cur->data == e) {return; // 无法删除前驱节点,直接返回}// 从第二个数据节点开始遍历LinkList next = cur->next;while (next != NULL) {if (next->data == e) {// 找到值为e的节点,删除其前驱节点(即cur)pre->next = next;free(cur);return; // 只删除第一个出现的节点的前驱,处理完后立即返回}// 未找到,指针后移pre = cur;cur = next;next = next->next;}
}