循环链表和在 C 函数的末尾插入

circular linked list and insert at end function in C

我想在 C 中创建一个循环链表。 但是我还不太了解链表。 好吧,程序将一个 int 获取到一个名为 list_end_ptr 的函数,该函数初始化循环链表并为 int 创建节点。 然后另一个函数 (insert_at_end) 将新节点放在初始化列表的末尾,returns 最后一个节点。 第三个函数通过获取结束节点并首先打印第一个输入的名称并以最后一个结束来打印链表(print_list)。

我的想法是只有一个端节点并且只使用它,但我无法让它工作。我设法让它部分工作,当我打印数据时,数据以名称条目的相反顺序打印(从最后输入到第一个)。

有什么想法吗?

#include <stdio.h> 
#include <stdlib.h> 
#include <strings.h>
#define SIZE 10
#define NUM_PER_LINE 3

typedef struct node
{
    char name[SIZE];   /* SIZE-1 χαρακτήρες και το '[=10=]' */
    struct node * next;
} CListNode;

void get_name(char *a);
void print_list(CListNode *end_ptr);
CListNode *initiate(int n);
CListNode *insert_at_end(CListNode *end_ptr, char *a);

int main(void) {
    CListNode *list_end_ptr;

    int n=6;
    list_end_ptr=initiate(n);
    print_list(list_end_ptr);

    return 0;
}

void get_name(char *a)
{
    char format[10];

    sprintf(format, "%%%ds", SIZE-1);
    scanf(format, a);
}

CListNode *insert_at_end(CListNode *end_ptr, char *a)
{
    CListNode *temp, *head=NULL;

    head=end_ptr->next;
    temp=(CListNode *) malloc(sizeof(CListNode));
    end_ptr->next=temp;
    strcpy(temp->name, a);
    temp->next=head;

    return temp;

}

CListNode *initiate(int n) {

    CListNode *end, *first=NULL;
    int i;
    char new_name;
    end=(CListNode *) malloc(sizeof(CListNode));
    if (end==0) {
        printf("Allocation error...\n");
        exit(0); }
    end->next=end;

    for (i=0; i<n; i++) {
        if (i<1) {
            printf("Enter the name of the %d person: ", i+1);
            get_name(&new_name);
            strcpy(end->name, &new_name);
            first=end;
        }
        else
        {
            printf("Enter the name of the %d person: ", i+1);
            get_name(&new_name);
            insert_at_end(end, &new_name);
        }
    }

    return end;
}

void print_list(CListNode *end_ptr)
{
    int i=1;
    CListNode *str_ptr;
    if (end_ptr == NULL)
        printf("\n List is empty");
    else
    {
        str_ptr = end_ptr->next;
        while (str_ptr !=  end_ptr)
        {
            printf("%s \t", str_ptr->name);
            str_ptr = str_ptr->next;
            if (i%NUM_PER_LINE==0) {
                printf("\n");
            }
            i++;
        }
        printf("%s\n", str_ptr->name);
    }
}

一般来说,在单向链表(这是你拥有的)的末尾插入是通过 next 指针迭代直到你得到 NULL 值的问题,并且然后创建一个节点,调整之前最后一个节点的next指针指向新节点

代码包括 <strings.h>,但应该是 <string.h>

此外,如果您当前的代码有 strcpy,您可能应该改用 strdupstrncpy 以确保您不会超出为 [分配的 SIZE =20=].

此代码存在许多问题,但这应该可以帮助您入门:

CListNode *initiate(int n) {
    CListNode *end, *first;
    int i;
    char new_name[SIZE];
    end = first = malloc(sizeof(*first));
    if (first == NULL) {
        printf("Allocation error...\n");
        exit(0); 
    }

    for (i=0; i<n; i++) {
        printf("Enter the name of the %d person: ", i+1);
        get_name(new_name);
        insert_at_end(end, new_name);
    }

    return end;
}

我的朋友,你没有为条件 i>0.The 更新结束指针你创建的第一个节点非常正确但是当你的代码开始执行 for 循环的 else 部分时,结束指针不是正确操作。这是您提供的代码的更正版本

对于初始化函数for循环的else部分

else
    {
      printf("Enter the name of the %d person: ", i+1);
      get_name(&new_name);
      ptr=insert_at_end(first,end, &new_name);/*insert_at_end returns temp*/
      end=ptr;
    }

insert at end 函数 returns temp 以便可以更新结束指针。

对于 insert_at_end 函数,只需替换行

 head=end_ptr->next;

head=first;

当然,你也必须在调用函数时传递第一个指针。

所以简而言之,您几乎完成了正确的工作,并进行了细微的修改,例如:

insert_at_end 函数返回值应放入一个指针中,该指针又用于更新结束。

我们最终得到了正确的代码。

别忘了更新函数原型 insert_at_end.It 应该是

CListNode *insert_at_end(CListNode *first,CListNode *end_ptr, char *a);