aa_bvc 发表于 2023-11-9 22:38:26

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

#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,但又报出类型转换错误。求大佬指点。万分感谢。我感觉我是被参数传递给绕晕了。

isdkz 发表于 2023-11-9 22:39:03

你在代码中遇到的问题是临时指针无法指向头指针。这是因为你在 delete_pos 函数中创建了一个临时指针 node* p = *head ,然后在循环中对 p 进行了移动,但是没有更新 head 指针的值。

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

下面是修改后的代码:

void delete_pos(list* head, int pos) {
    if (pos < 0) {
      printf("Invalid position.\n");
      return;
    }
    if (pos == 0) {
      delete_head(head);
      return;
    }
    node* p = *head;
    node* q = 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;
    }
    if (q == NULL) {
      *head = p->next;
    } else {
      q->next = p->next;
    }
    free(p);
}


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

希望这可以帮助你解决问题!如果还有其他问题,请随时提问。
页: [1]
查看完整版本: 自己写了按位删除节点的代码,发现临时指针无法指向头指针。头晕了