【问题标题】:How to add & delete node in Double Linked List with C Language?如何使用 C 语言在双链表中添加和删除节点?
【发布时间】:2020-10-02 02:31:52
【问题描述】:

我有 3 个结构节点:

struct Student{
    char id[255];
    char name[255];
    float gpa;
};
struct Elemen{
    struct Student *mhs;
    struct Elemen *next;
};
struct List{
    struct Elemen *first;
};

如果我向学生节点添加数据,已经添加的数据不能更多,代码如下:

int main() 
{ 
    head = (struct List*)malloc(sizeof(struct List));   
    after = (struct List*)malloc(sizeof(struct List));  
    last = (struct List*)malloc(sizeof(struct List));
    
    after->first = (struct Elemen*)malloc(sizeof(struct Elemen));
    head->first = (struct Elemen*)malloc(sizeof(struct Elemen));
    last->first = (struct Elemen*)malloc(sizeof(struct Elemen));
  
    after->first->next = (struct Elemen*)malloc(sizeof(struct Elemen));
    head->first->next = (struct Elemen*)malloc(sizeof(struct Elemen));
    last->first->next = (struct Elemen*)malloc(sizeof(struct Elemen));
  
    after->first->mhs = (struct Student*)malloc(sizeof(struct Student));
    head->first->mhs = (struct Student*)malloc(sizeof(struct Student));
    last->first->mhs = (struct Student*)malloc(sizeof(struct Student));
    
    strcpy(head->first->mhs->id, "1"); 
    strcpy(head->first->mhs->name, "Student 1"); 
    head->first->mhs->gpa = 4;
    head->first->next = after->first;
    
    strcpy(after->first->mhs->id, "2"); 
    strcpy(after->first->mhs->name, "Student 2");
    after->first->mhs->gpa = 5;
    after->first->next = last->first;
    
    strcpy(last->first->mhs->id, "3"); 
    strcpy(last->first->mhs->name, "Student 3");
    last->first->mhs->gpa = 6;
    last->first->next = NULL;
    
    printAllElemen(head);
    return 0; 
}

void printAllElemen(struct List *e){
    printf("ID\t|Name\t|GPA\n");
    while(e->first != NULL)
    {
        printf("%s\t|%s\t|%.2f\n", e->first->mhs->id, e->first->mhs->name, e->first->mhs->gpa);
        e->first = e->first->next;
    }
}

这样的程序示例:

void addFirst(char id[], char name[], float gpa, struct List *e);
void addAfter(struct Elemen *prev, char id[], char name[], float gpa, struct List *e);
void addLast(char id[], char name[], float gpa, struct List *e);
void deleteFirst(struct List *e);
void deleteAfter(struct Elemen *prev, struct List *e);
void deleteLast(struct List *e);

我的问题是如何在功能上添加数据节点,并且节点列表中的数据可以多于1个?

谢谢

【问题讨论】:

  • 您可能会发现Doubly-Linked List of Integers - Remove Rand Nodes Check 很有帮助。您可以用您的结构替换整数数据,只需添加代码来填充每个成员。 (您通常会将结构成员的初始化移动到 createnode() 函数,该函数为节点分配和初始化结构,并将指向新节点的指针返回到 add()
  • 在C中,malloc的返回不需要强制转换,没有必要。见:Do I cast the result of malloc?
  • 您的代码最大的问题是您似乎对如何使用列表感到困惑。您只需分配一个节点。如果它是唯一节点,则nextprev 指针为NULL。当你创建另一个节点时,你用新节点的地址更新第一个节点next指针,用第一个地址更新新节点prev。您不分配节点,然后再次分配 nextprev 指针——这些是指向下一个节点的“链接”,即列表如何“链接”在一起。
  • @David C.Rankin 谢谢先生的建议。我会研究你说的。
  • 慢慢来。列表在 C 中经常使用。有多种风格,单链接、双链接、循环等。如果您编译并运行链接代码,它将提供一个很好的示例,用于在双链上进行列表操作 -链表(它只是创建一个包含 16 个节点且值为 1-16 的列表,然后对一个值为 1-16 的数组进行洗牌,以随机顺序删除所有节点以完全执行该列表。)您一次分配一个节点然后使用prevnext指针将所有节点连接在一起,first->prev == NULLlast->next == NULL

标签: c linked-list doubly-linked-list


【解决方案1】:

在这里重写代码。

    void addFirst(const char *id, const char *name, float gpa, struct List *e);
        void addAfter(struct Elemen *prev, const char *id, const char *name, float gpa, struct List *e);
        void addLast(const char *id, const char *name, float gpa, struct List *e);
        void deleteFirst(struct List *e);
        void deleteAfter(struct Elemen *prev, struct List *e);
        void deleteLast(struct List *e);
        
        
        void addFirst(const char *id, const char *name, float gpa, struct List *e){
            struct Elemen*newE = (struct Elemen*)malloc(sizeof(struct Elemen));
            newE->mhs = (struct Student*)malloc(sizeof(struct Student));
            strcpy(newE->mhs->id, id);
            strcpy(newE->mhs->name,name);
            newE->mhs->gpa = gpa;
            newE->next = e->first->next;
            e->first = newE;
        }
        void addAfter(struct Elemen *prev, const char *id, const char *name, float gpa, struct List *e){
            struct Elemen*newE = (struct Elemen*)malloc(sizeof(struct Elemen));
            newE->mhs = (struct Student*)malloc(sizeof(struct Student));
            strcpy(newE->mhs->id, id);
            strcpy(newE->mhs->name,name);
            newE->mhs->gpa = gpa;
            newE->next = 0;
            struct Elemen*ptr = e->first;
            if(ptr == 0){ // emptry list
                e->first = newE;
                return;
            }
            while(ptr != prev) ptr = ptr->next;
            newE->next = ptr->next;
            ptr->next = newE;
        }
        
        void addLast(const char *id, const char *name, float gpa, struct List *e){
            struct Elemen*newE = (struct Elemen*)malloc(sizeof(struct Elemen));
            newE->mhs = (struct Student*)malloc(sizeof(struct Student));
            strcpy(newE->mhs->id, id);
            strcpy(newE->mhs->name,name);
            newE->mhs->gpa = gpa;
            newE->next = 0;
            // insert new node
            struct Elemen *ptr = e->first;
            if(ptr == 0){ // there are no nodes in list.
                e->first = newE;
            }else{
                while(ptr->next != 0) ptr = ptr->next; // find last node
                ptr->next = newE;
            }
        }
        void deleteFirst(struct List *e){
            if(e->first == 0) return; // empty list
            struct Elemen*firptr = e->first;
            e->first = e->first->next;
            free(firptr);
        }
        void deleteAfter(struct Elemen *prev, struct List *e){
            struct Elemen*ptr = e->first;
            if(ptr == 0){ // emptry list
                return;
            }
            while((ptr != prev) && ptr->next != 0) ptr = ptr->next;
            
            Elemen*ptr1 = ptr->next;
            ptr->next = ptr->next->next;
            free(ptr1);
        }
        void deleteLast(struct List *e){
            struct Elemen*ptr = e->first;
            struct Elemen*prev = ptr;
            if(ptr == 0){ // emptry list
                return;
            }
            if(ptr->next == 0) {
free(e->first);e->first = 0;return;
} // only first node exists.
            while((ptr->next != 0) { prev = ptr;ptr = ptr->next;}
            free(ptr);
            prev->next = 0;
            
        }
        
        void printAllElemen(struct List *e){
            printf("ID\t|Name\t|GPA\n");
            struct Elemen*ptr = e->first;
            while(ptr != 0)
            {
                printf("%s\t|%s\t|%.2f\n", ptr->mhs->id, ptr->mhs->name, ptr->mhs->gpa);
               ptr = ptr->next;
            }
        }
        
        
        
        
        int main(){
        struct List*mList = (struct List*)malloc(sizeof(struct List));
        mList->first = 0;
        addFirst("1", "stud1", 4, mList);
        addLast("2", "std2", 5, mList);
        addLast("3", "std3", 6, mList);
        printAllElemen(head);
        return 0; 
        }

【讨论】:

  • 谢谢先生,您的代码正在运行,但 addFirst 过程中有一个小错误,newE->next = e->first->next; 我将其替换为newE->next = e->first;
  • procedure deleteLast 它不起作用先生?如何解决?删除节点后我无法打印AllElemen,您能解释一下吗?
  • 我重写函数:deleteLast
猜你喜欢
  • 2011-03-12
  • 2015-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多