鱼C论坛

 找回密码
 立即注册
查看: 260|回复: 1

自己写了按位删除节点的代码,发现临时指针无法指向头指针。头晕了

[复制链接]
发表于 2023-11-9 22:38:26 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <malloc.h>

typedef struct node {
    int data; // 数据域,可以是任意类型
    struct node* next; // 指针域,指向下一个节点
} node;

// 定义一个指针类型,用来表示链表的头指针
typedef node* list;

// 定义一个函数,用来在链表的尾部插入一个节点
void insert_tail(list* head, int data) {
    node* q = (node*)malloc(sizeof(node)); // 创建一个新的节点,分配内存空间
    q->data = data; // 给新节点的数据域赋值
    q->next = NULL; // 给新节点的指针域赋值为NULL
    if (*head == NULL) {// 如果链表为空,直接把新节点作为头节点
        *head = q;
    }
    else { // 如果链表不为空,找到尾节点,把新节点接在后面
        node* p = *head; // 创建一个临时指针,指向头节点
        while (p->next != NULL) { // 循环遍历,直到找到尾节点
            p = p->next;
        }
        p->next = q; // 把新节点接在尾节点后面
    }
}
void delete_head(list* head) {
    if (*head == NULL) { // 如果链表为空,无法删除
        printf("The list is empty.\n");
        return;
    }
    node* p = *head; // 创建一个临时指针,指向头节点
    *head = p->next; // 更新头指针为头节点的下一个节点
    free(p); // 释放头节点的内存空间
}
// 定义一个函数,用来删除链表的指定位置的节点
void delete_pos(list* head, int pos) {
    if (pos < 0) { // 如果位置小于0,无效
        printf("Invalid position.\n");
        return;
    }
    if (pos == 0) { // 如果位置等于0,相当于删除头节点
        delete_head(head);
        return;
    }
    node* p = *head; // 创建一个临时指针,指向头节点
    node* q = NULL; // 创建一个临时指针,指向NULL
    int i = 0; // 创建一个计数器,记录当前位置
    while (p != NULL && i < pos) { // 循环遍历,直到找到删除位置的节点或到达链表尾部
        q = p; // 记录删除位置的前一个节点
        p = p->next;
        i++;
    }
    if (p == NULL) { // 如果到达链表尾部,无法删除
        printf("The position is out of range.\n");
        return;
    }
    q->next = p->next; // 给删除位置的前一个节点的指针域赋值为删除位置的后一个节点
    free(p); // 释放删除位置的节点的内存空间
}

// 定义一个函数,用来打印链表的数据
void print_list(list head) {
    node* p = head; // 创建一个临时指针,指向头节点
    while (p != NULL) { // 循环遍历,直到链表尾部
        printf("%d ", p->data); // 打印当前节点的数据
        p = p->next; // 指针后移
    }
    printf("\n"); // 打印换行符
}

int main() {
    list head = NULL; // 创建一个空的链表
    int n, data, pos; // 创建一些变量,用来存储输入的数据
    printf("请输入要插入的节点个数:\n"); // 打印提示信息
    scanf("%d", &n); // 读取输入的节点个数
    printf("请输入要插入的节点的数据:\n"); // 打印提示信息
    for (int i = 0; i < n; i++) { // 循环插入节点
        scanf("%d", &data); // 读取输入的节点数据
        insert_tail(&head, data); // 调用插入函数,把数据插入到链表尾部
    }
    printf("插入后的链表为:\n"); // 打印提示信息
    print_list(head); // 调用打印函数,打印链表的数据
    printf("请输入要删除的节点的位置:\n"); // 打印提示信息
    scanf("%d", &pos); // 读取输入的节点位置
    delete_pos(&head, pos); // 调用删除函数,把指定位置的节点删除
    printf("删除后的链表为:\n"); // 打印提示信息
    print_list(head); // 调用打印函数,打印链表的数据
    return 0; // 返回程序正常退出的状态码
}
加红的地方就是出错的地方,但是我不会改了,头疼,我断点调试后,发现在这个地方临时指针无法指向头指针,我想直接换成node*p=head,但又报出类型转换错误。求大佬指点。万分感谢。我感觉我是被参数传递给绕晕了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-11-9 22:39:03 | 显示全部楼层
你在代码中遇到的问题是临时指针无法指向头指针。这是因为你在 delete_pos 函数中创建了一个临时指针 node* p = *head ,然后在循环中对 p 进行了移动,但是没有更新 head 指针的值。

解决这个问题的方法是将 head 指针作为参数传递给 delete_pos 函数,并在函数中更新 head 指针的值。

下面是修改后的代码:

  1. void delete_pos(list* head, int pos) {
  2.     if (pos < 0) {
  3.         printf("Invalid position.\n");
  4.         return;
  5.     }
  6.     if (pos == 0) {
  7.         delete_head(head);
  8.         return;
  9.     }
  10.     node* p = *head;
  11.     node* q = NULL;
  12.     int i = 0;
  13.     while (p != NULL && i < pos) {
  14.         q = p;
  15.         p = p->next;
  16.         i++;
  17.     }
  18.     if (p == NULL) {
  19.         printf("The position is out of range.\n");
  20.         return;
  21.     }
  22.     if (q == NULL) {
  23.         *head = p->next;
  24.     } else {
  25.         q->next = p->next;
  26.     }
  27.     free(p);
  28. }
复制代码


在修改后的代码中,我添加了一个判断语句来检查 q 指针是否为 NULL ,如果是 NULL ,说明要删除的节点是头节点,需要更新 head 指针的值。

希望这可以帮助你解决问题!如果还有其他问题,请随时提问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 07:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表