linkedList.c:

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

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

typedef struct Node *node;

node createNode(int val) {
    node newNode = (node)malloc(sizeof(struct Node));
    if (newNode == NULL) {
        printf("cannot allocate memory");
        exit(EXIT_FAILURE);
    }
    newNode->data = val;
    newNode->next = NULL;
    return newNode;
}

node insertFront(node head, int val) {
    node insert = createNode(val);
    if (head == NULL) {
        head = insert;
        return head;
    }
    insert->next = head;
    head = insert;
    return head;
}

node insertTail(node head, int val) {
    node insert = createNode(val);
    node temp = head;
    if (head == NULL) {
        head = insert;
        return head;
    }
    while (temp->next != NULL)
        temp = temp->next;
    temp->next = insert;
    insert->next = NULL;
    return head;
}

node listSearch(node head, int val) {
    node temp = head;
    while (temp != NULL) {
        if (temp->data == val) {
            printf("%d\n", 1);
            return temp;
        }
        temp = temp->next;
    }
    printf("%d\n", -1);
    return NULL;
}

node insertAfter(node head, int afterThisVal, int val) {
    node afterThis = listSearch(head, afterThisVal);
    if (afterThis == NULL)
        return head;
    if (afterThis->next == NULL) {
        head = insertTail(head, val);
        return head;
    }
    node insert = createNode(val);
    node temp = afterThis->next;
    afterThis->next = insert;
    insert->next = temp;
    return head;
}

node insertBefore(node head, int beforeThisVal, int val) {
    node beforeThis = listSearch(head, beforeThisVal);
    if (beforeThis == NULL)
        return head;
    if (beforeThis == head) {
        head = insertFront(head, val);
        return head;
    }
    
    node prev = head;
    while (prev->next != beforeThis)
        prev = prev->next;

    node insert = createNode(val);
    prev->next = insert;
    insert->next = beforeThis;
    return head;
}

node deleteFirst(node head) {
    if (head == NULL) {
        printf("%d\n", -1);
        return head;
    }
    node temp = head;
    head = head->next;
    printf("%d\n", temp->data);
    free(temp);
    return head;
}

node deleteLast(node head) {
    if (head == NULL) { 
        printf("%d\n", -1);
        return head;
    }
    node temp = head;
    node prev = NULL;
    while (temp->next != NULL) {
        prev = temp;
        temp = temp->next;
    }
    if (prev != NULL)
        prev->next = NULL;
    printf("%d\n", temp->data);
    free(temp);
    return head;
}

node deleteNode(node head, int val) {
    node found = listSearch(head, val);
    if (found == NULL) {
        printf("%d\n",-1);
        return head;
    }
    else if (found == head) {
        head = deleteFirst(head);
        return head;
    }
    else if (found->next == NULL) {
        head = deleteLast(head);
        return head;
    }
    node prev = head;
    while (prev->next != found)
        prev = prev->next;
    prev->next = found->next;
    printf("%d\n", found->data);
    free(found);
    return head;
}

void display(node head) {
    if (head == NULL)
        return;
    node temp = head;
    while (temp->next != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("%d\n", temp->data);
}

node reverseList(node head) {
    node i = head;
    node j = NULL;
    node k = NULL;

    while (i != NULL) {
        k = j;
        j = i;
        i = i->next;
        j->next = k;
    }
    return j;
}

node reverseEven(node head) {
    node oddHead = head;
    node odd = head;
    node evenHead = head->next;
    node even = head->next;
    node temp1 = NULL;
    node temp2 = NULL;
    while (odd->next != NULL && even->next != NULL) {
        odd->next = even->next;
        odd = odd->next;
        even->next = odd->next;
        even = even->next;
    }
    if ((odd != NULL && odd->next != NULL) || (even != NULL && even->next != NULL)) {
        odd->next = NULL;
        even->next = NULL;
    }
    display(evenHead);
    display(oddHead);
    evenHead = reverseList(evenHead);
    even = evenHead;
    odd = oddHead;
    while (even != NULL && odd != NULL) {
        temp1 = odd;
        odd = odd->next;
        temp1->next = even;
        temp2 = even;
        even = even->next;
        temp2->next = odd;
    }
    return head;
}

int main() {
    char op[2];
    node head = NULL;
    int inp1, inp2;
    scanf("%s", op);
    while (strcmp(op, "e") != 0) {
        if (strcmp(op, "f") == 0) {
            scanf("%d", &inp1);
            head = insertFront(head, inp1);
            display(head);
        }
        else if (strcmp(op, "t") == 0) {
            scanf("%d", &inp1);
            head = insertTail(head, inp1);
            display(head);
        }
        else if (strcmp(op, "a") == 0) {
            scanf("%d", &inp1);
            scanf("%d", &inp2);
            head = insertAfter(head, inp2, inp1);
            display(head);
        }
        else if (strcmp(op, "b") == 0) {
            scanf("%d", &inp1);
            scanf("%d", &inp2);
            head = insertBefore(head, inp2, inp1);
            display(head);
        }
        else if (strcmp(op, "d") == 0) {
            scanf("%d", &inp1);
            head = deleteNode(head, inp1);
            display(head);
        }
        else if (strcmp(op, "i") == 0) {
            head = deleteFirst(head);
            display(head);
        }
        else if (strcmp(op, "l") == 0 ){
            head = deleteLast(head);
            display(head);
        }
        else if (strcmp(op, "s") == 0) {
            scanf("%d", &inp1);
            listSearch(head, inp1);
        }
        else if (strcmp(op, "r") == 0) {
            head = reverseList(head);
        }
        else if (strcmp(op, "ds") == 0) {
            display(head);
        }
        else if (strcmp(op, "re") == 0) {
            head = reverseEven(head);
        }
        else {
            printf("INVALID\n");
        }
        scanf("%s", op);
    }
    return 1;
}

我的代码以菜单驱动程序的形式实现了链表的所有功能.

input.txt:

f 7
t 10
a 11 7
b 12 11
d 10
i
l
s 12
s 6
t 15
f 14
f 20
ds
r
re
e

我看到的错误是分段错误. 在input.txt中的f 20之后为ds(显示函数),Head随机获得一个垃圾值,并显示mingw_ovr_Bullett_va_list部分 我不确定我犯了什么错误.

请原谅我可能在代码中使用的不良实践,因为我仍在学习C语言.

推荐答案

函数deleteLast中有一个错误:您必须测试head是否已经是最后一个 node ,并在释放temp后返回NULL.在此之后从head读取时,如果取消引用无效的指针,则会出现未定义的行为.未定义的行为意味着任何事情都可能发生,包括不同运行或不同计算机上的不同行为.

以下是修改后的版本:

node deleteLast(node head) {
    if (head == NULL) { 
        printf("%d\n", -1);
        return head;
    }
    node temp = head;
    node prev = NULL;
    while (temp->next != NULL) {
        prev = temp;
        temp = temp->next;
    }
    if (prev == NULL) {
        head = NULL;
    } else {
        prev->next = NULL;
    }
    printf("%d\n", temp->data);
    free(temp);
    return head;
}

main中还有另一个问题:您将op定义为一个由2个char组成的数组:这个数组最多只能存储一个包含一个字符和一个空字节的字符串,但是您从包含scanf("%s", op)的用户处读取,因此任何长度超过1个字符的输入单词都将导致缓冲区溢出,因为scanf()不知道目标数组有多长.

您应该将数组加长,并告知scanf()要存储到长度介于%s之间的目标数组中的最大字符数:

    char op[20];
    node head = NULL;
    int inp1, inp2;
    if (scanf("%19s", op) != 1)
        return 1;

C++相关问答推荐

当我try 计算一个多项时,看到segfault.我做错了什么?

如何将FileFilter添加到FileDialog GTK 4

增加getaddrinfo返回的IP地址数量

如何将字符串argv[]赋给C中的整型数组?

如何在C宏中确定 struct 中元素的类型?

我无法让LLDB正确运行我的可执行文件

当输入负数时,排序算法存在问题

如何在ASM中访问C struct 成员

在Rust和C之间使用ffi时如何通过 struct 中的[U8;1]成员传递指针

CGO:如何防止在使用CGO在包中包含C头文件时出现多个定义...&q;错误?

为什么realloc函数在此代码中修改变量?

Zlib:解压缩大文件导致";无效代码长度设置";错误

有没有一种方法可以用C创建保留限定符的函数?

Linux/C:带有子进程的进程在添加waitid后都挂起

如何在C中处理流水线中的a、n命令?

Malloc和对齐

C 程序不显示任何输出,但它接受 CS50 Lab1 的输入问题

将指针的地址加载到寄存器内联拇指组件中

std::malloc/calloc/realloc/free 与纯 C 的 malloc/calloc/realloc/free 有什么不同

C simd _m128 晶圆厂