【问题标题】:circular linked list and insert at end function in C循环链表并在C中的末尾函数插入
【发布时间】:2015-06-16 04:20:45
【问题描述】:

我正在尝试在 C 中创建一个循环链表。 但是我对链表还不是很了解。 好吧,程序将一个 int 传递给一个名为 list_end_ptr 的函数,该函数初始化循环链表并为该 int 创建节点。 然后另一个函数(insert_at_end)将新节点放在初始化列表的末尾并返回最后一个节点。 第三个函数通过获取结束节点并首先打印第一个输入的名称并以最后一个结束来打印链接列表(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 χαρακτήρες και το '\0' */
    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);
    }
}

【问题讨论】:

    标签: c linked-list


    【解决方案1】:

    通常,在单链表的末尾插入(这就是您所拥有的)是遍历 next 指针直到获得 NULL 值,然后创建一个节点,然后调整前一个最后一个节点的next指针指向新节点。

    代码包括&lt;strings.h&gt;,但应该是&lt;string.h&gt;

    此外,如果您当前的代码有 strcpy,您可能应该改用 strdupstrncpy 以确保不会超出分配给 SIZEname

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

    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;
    }
    

    【讨论】:

    • 这仍然与最初的结果相同。
    • @ToroLoco:是的,您还需要解决许多其他问题。
    • 事实上,我的打印功能适用于我使用循环列表所做的另一个实现,并给了我正确的顺序。但是现在它返回了一个相反的顺序,所以它必须是 insert_at_end 函数将节点插入到开头而不是结尾处。但我不知道为什么以及是否会发生这种情况。
    【解决方案2】:

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

    对于initial函数的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 函数返回 temp,以便更新结束指针。

    对于 insert_at_end 函数,只需替换该行

     head=end_ptr->next;
    

    head=first;
    

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

    所以简而言之,您几乎已经完成了这项工作,并进行了一些细微的修改,例如:

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

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

    不要忘记更新函数insert_at_end的原型。应该是

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

    【讨论】:

    • 虽然奇​​怪,但它适用于 5 个字符或更少字符的名称。
    • 问题是这是一个练习代码,insert_at_end 不能改变:(
    • 我所有的代码都是正确的,只是认为缺少的是一个指针,用于获取从 insert_at_end 返回的结束节点。我输入了 ptr=insert_at_end,现在它可以工作了。
    • 如果名称超过5个字符,程序只在一个节点终止。你注意到了吗?
    猜你喜欢
    • 2018-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 1970-01-01
    • 1970-01-01
    • 2014-07-14
    相关资源
    最近更新 更多