c - C-删除节点函数中的双向链表

标签 c data-structures doubly-linked-list

双向链表节点是在主函数中创建的。安德和标题定义。在删除节点函数处中断 - ender 为空。

释放最后一个和第一个输入的内存的最佳方法是什么,即:删除:233,A 和 888,F?

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

typedef struct record {
    int idnumber;
    char initial;
    struct record *prevStudent;
    struct record *nextStudent;
} STUDENT;

STUDENT *header = NULL;  //pointer to the start of linked list
STUDENT *ender = NULL;   //pointer to the end of the linked list

void Makenode(int x, char y);
void deletenode();

int main() {
    Makenode(233, 'A');
    Makenode(456, 'H');
    Makenode(746, 'G');
    Makenode(888, 'F');
    deletenode();

    fflush(stdin);
    getchar();
    return 0;
}

void Makenode(int x, char y) {
    STUDENT *ptr;

    ptr = (STUDENT *)malloc(sizeof(STUDENT));
    if (ptr != NULL) {
        ptr->idnumber = x;
        ptr->initial = y;
        ptr->nextStudent = header;
        ptr->prevStudent = NULL;

        if (header == NULL)
            ender = ptr;
        else
            header->prevStudent = ptr;

        header = ptr;

    } else {
        printf("Memory not allocated\n");
    }
}

void deletenode() {
    //delete the first and the last node of the linked list
    STUDENT *p = header, *q = ender;
    char c;

    printf("Are you sure you want to delete Y/N:\n");
    fflush(stdin); c=getchar();
    while (c == 'Y' || c == 'y') {
        ender=ender->nextStudent;
        header=header->prevStudent;
        free(p); free(q);
    }
}   

最佳答案

您的删除函数使链表处于非法状态。在任何时候(除了暂时在您的插入和删除函数中),以下必须为真:

  • 如果 header 为 null,则 ender 也必须为 null,并且列表为空。
  • 如果一个节点 p 有一个到 p->next 的非空链接,那么 p->next->prev == p.
  • 同样,如果节点 p 有到 p->prev 的非空链接,则 p->prev->next == p
  • 头部没有前一个节点;安德没有下一个节点。

这些是链表的不变量。

如果您检查要删除的代码:

void deletenode()
{
    STUDENT *p = header, *q = ender;

    ender=ender->nextStudent;
    header=header->prevStudent;
    free(p); free(q);
}

你可以看到你只是将headerender设置为NULL,因为那是ender->nextStudentheader->prevStudent 是。但即使逆转也无济于事,因为您必须更新相邻节点的链接。

这里有两个函数 - 每个任务一个 - 有效:

void delete_first()
{
    STUDENT *p = header;

    if (p) {
        if (p->nextStudent == NULL) {
            header = ender = NULL;
        } else {
            p->nextStudent->prevStudent = NULL;
            header = p->nextStudent;
        }
        free(p);
    }
}

void delete_last()
{
    STUDENT *p = ender;

    if (p) {
        if (p->prevStudent == NULL) {
            header = ender = NULL;
        } else {
            p->prevStudent->nextStudent = NULL;
            ender = p->prevStudent;
        }
        free(p);
    }
}

关于c - C-删除节点函数中的双向链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24016775/

相关文章:

c++ - 我是否必须使用 std::shared_ptr 删除对对象的所有引用

c - 双链表中在末尾插入一个节点并在开头删除一个节点

c - 带游程的稀疏二元矩阵的最优空间高效存储方案

c - C 程序中的 .eh_frame 部分有什么用?

python - Python 中的非二叉树数据结构

用于存储数百万个int16的c++数据结构

java - 无法解决 Java 双端队列迭代错误

c - 如何将 Signed Char 与文字常量进行比较?

C - 具有可变数量参数和命令行参数的函数

python-3.x - 二叉搜索树插入方法无法插入任何节点