插入链接列表

时间:2013-11-03 04:39:13

标签: c

我还在学习链表,并且一直在尝试创建一个插入链表的方法。

我只是想知道这是否是正确的插入方式?另外,我如何打印整个链表,以便打印abc

之类的内容

这就是我所拥有的:

struct node {
   char value;
   struct node *next;
};

typedef struct node item;

void main() {
    InsertChar('a');
    InsertChar('b');
    InsertChar('c');
}

void InsertChar(char s) {
    item *curr, *head;

    head = NULL;

    curr = (item *)malloc(sizeof(item));
    curr->value = s;
    curr->next = head;
    head = curr;

    while(curr) {
        printf("%c\n", curr->value);
        curr = curr->next;
    }
}

2 个答案:

答案 0 :(得分:3)

首先,您的函数InsertChar每次都会覆盖head的值(head = curr),因此您最终会得到一个项目的列表。

您需要声明存储head的内容。

struct list
{
    struct node *head;
};

现在,您可以通过浏览每个list轻松打印node

void PrintList(struct list* list)
{
    struct node *curr = list->head;

    while (curr != NULL)
    {
        printf("%c\n", curr->value);
        curr = curr->next;
    }
}

现在您需要修改InsertChar,以便列表中的最后一项(您将如何找到它?)指向您的新项目。我会把它留给你:)

答案 1 :(得分:0)

您可能已经注意到,您无法从外部InsertChar()访问该列表(如果有的话)。您不使用全局变量,也不输入或输出它。

更好的实施:

item * InsertChar(item ** phead, char s) {
    item * curr;

    // First, allocate a new item and fill it.
    curr = malloc(sizeof(item)); // no need to cast here
    if (curr) { // only if malloc() succeeds
        curr->value = s;
        curr->next = *phead;
        *phead = curr;
    }
    return curr;
}

// InsertChar() is only supposed to insert, not to print.
void PrintList(item * head) {
    item * curr = head;   
    while(curr) {
        printf("%c", curr->value); // omit the line break as you want abc
        curr = curr->next;
    }
    printf("\n"); // now the line break
    return;
    // alternative implementation for while loop:
    for(curr=head; curr; curr=curr->next) {
        printf("%c\n", curr->value);
    }
}

void FreeList(item * head) {
    item * curr = head;   
    while(curr) {
        item * next = curr->next; // read it out before freeing.
        free(curr);
        curr = next;
    }
}

这样你就可以了吗

int main() {
    item * list = NULL; // empty for now, no contents.
    char success = 1;
    success = success && InsertChar(&list, 'a');
    success = success && InsertChar(&list, 'b');
    success = success && InsertChar(&list, 'c');
    if (!success) {
        printf("Oops?");
        FreeList(list);
        return 1;
    }
    PrintList(list);
    FreeList(list); // clean up.
}

糟糕?我没有测试它,但在我看来,它打印“cba”。为什么会这样?好吧,InsertChar()将所有内容都放在了开头。

如何解决这个问题?

我们可以创建一个AppendChar()函数。但这带来了我们陷入Schlemiel the Painter's algorithm陷阱的危险:从一开始就开始寻找合适的地方。因此,我将指出另一种方法:

int main() {
    item * list = NULL; // empty for now, no contents.
    item * cursor = InsertChar(&list, 'a');
    if (!cursor) goto error;
    // cursor now contains our first entry.
    // We put the next one to cursor->next:
    cursor = InsertChar(&cursor->next, 'b');
    if (!cursor) goto error;
    cursor = InsertChar(&cursor->next, 'c');
    if (!cursor) goto error;
    PrintList(list);
    FreeList(list); // clean up.
    return 0;
  error:
    printf("Oops?");
    FreeList(list);
    return 1;
}

我不确定我是否正确(没有测试),但这应该是要走的路。

如果您是其中之一,在任何情况下都被告知goto是邪恶的,请随意以不同的方式实现错误处理。