首页 > 解决方案 > 删除链接排序列表中的第一个元素

问题描述

我是新来的,这实际上是我的第一个问题。

我写了这段代码,我不能删除列表的第一个元素,我可以以某种方式删除其他元素。我对函数 reverse_list 也有问题,我相信这是因为我没有将参数作为参考传递。

我可以在 C 编程的参数中使用 & 吗?

#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node * next;
};


struct Node * build_sorted_list () {
    struct Node * head = NULL, * temp, * rear, * front;
    int num;
    printf ("please enter a number:");
    scanf ("%d", &num);
    while (num != 0) {
        temp = (struct Node *) malloc (sizeof (struct Node));
        if (temp == NULL) {
            printf ("god damn");
            break;
        }
        temp -> data = num;
        if (head == NULL) {
            temp -> next = NULL;
            head = temp;
        }
        else if (num <= head -> data) {
            temp -> next = head;
            head = temp;
        }
        else {
            rear = head;
            front = rear -> next;
            while (front != NULL && front -> data <= num) {
                rear = front;
                front = front -> next;
            }
            temp -> next = front;
            rear -> next = temp;
        }
        printf ("enter number please:\n");
        scanf ("%d", &num);
    }
    return head;
}


struct Node * reverse_list (struct Node * head) {
    struct Node * rear, * mid, * front;
    if (head != NULL || head -> next == NULL) {
        return head;
    }
    rear = head;
    mid = rear ->next;
    front = mid -> next;
    while (front != NULL) {
        mid -> next = rear;
        rear = mid;
        mid = front;
        front = front ->next;
    }
    mid -> next = rear;
    head -> next = NULL;
    head = mid;
    return head;
}


struct Node * delete_num (int wanted, struct Node * head) {
    struct Node * rear, * front;
    if (head == NULL) {
        return head;
    }
    if (head -> data == wanted) {
        struct Node * temp = head;
        head = head -> next;
        temp = NULL;
        return head;
    }
    rear = head;
    front = head -> next;
    while (front != NULL) {
        if (front -> data == wanted) {
            break;
        }
        rear = front;
        front = front -> next;
    }
    if (front != NULL) {
        rear -> next = front -> next;
    }
    free (front);
    return head;
}


int main() {
    struct Node * head;
    int wanted;
    head = build_sorted_list(); /* Please pretend this function exists */
    reverse_list (head);

    printf ("please enter a number to delete:");
    scanf ("%d", &wanted);
    delete_num (wanted, head);

    free_list (head);

    return 0;
}

标签: clinked-listpass-by-reference

解决方案


作为管理数据结构的递归函数的经验法则。结构上的操作应该返回结构。

根据定义,链表是:

  • 一个空列表。
  • 一个有值的节点,一个链表作为它的尾部。

链表具有递归性质。您需要非常小心,尽管代码量很短,但递归函数非常复杂。

在您的主要功能中,您有一个头指针。假设头部保持不变是不安全的。实际上,当您删除第一个元素(头部)时,您的问题就出现了。

您的删除应该是这样的:

struct Node * delete_num(int wanted, struct Node * head){
    if( head == NULL)
        return NULL;    //Reached the end of the line, nothing to do.

    if( head->data != wanted )
        head->next = delete_num(wanted, head->next);    //Haven't reached it yet, but 
                                                        //the element must be down 
                                                        //the line, I want to update
                                                        //my next in case it's the 
                                                        //next node.

    if(head->data == wanted){
         struct Node * aux = head;
         head = head->next;
         free(aux);
    }

    return head;
}

这是假设您只想删除一个元素并且您的列表不允许重复值。

你从 main 调用这个函数应该是:

head = delete_num(wanted, head);

安德烈斯


推荐阅读