双链表。代码工作......应该吗?比其他解决方案少得多的代码

时间:2016-07-27 22:05:15

标签: c pointers linked-list

我正在通过指针' '用C'编程作者:Kochan。

我编写了一个创建双链表的程序。它首先打印值。然后它继续调用函数来删除条目。这些值会再次打印出来。

最后,调用一个附加函数来添加一个条目,然后再次打印。

现在,我的代码有效。你可以在这里看到它:

#include <stdio.h>


struct entry
    {
        int value;
        struct entry *next;
        struct entry *previous;
    };

void removeEntry(struct entry *start);
void insertEntry(struct entry *addOn, struct entry *element);

int main (void)
{

    //declarations
    struct entry n1, n2, n3, addOn;
    struct entry *list_pointer = &n1;


    //creates list values and links
    n1.value = 100;
    n1.next = &n2;
    n1.previous = list_pointer;

    n2.value = 200;
    n2.next = &n3;
    n2.previous = &n1;

    n3.value = 300;
    n3.next = (struct entry *) 0;
    n3.previous = &n2;

    //prints out all list values
    while(list_pointer != (struct entry *) 0)
    {
        printf("%i\n", list_pointer->value);
        list_pointer = list_pointer->next;
    }

    printf("\n");

    //resets list_pointer back to start
    list_pointer = &n1;

    //calls function and removes n2 from list by directly linking n1 to n3
    removeEntry(&n2);

    //print out amended list
    while(list_pointer != (struct entry *) 0)
    {
        printf("%i\n", list_pointer->value);
        list_pointer = list_pointer->next;
    }

    printf("\n");

    list_pointer = &n1;
    insertEntry(&addOn, &n3);

    //print out amended list
    while(list_pointer != (struct entry *) 0)
    {
        printf("%i\n", list_pointer->value);
        list_pointer = list_pointer->next;
    }

    return 0;
}

void removeEntry(struct entry *start)
{
    start->previous->next = start->next;
}

void insertEntry(struct entry *addOn, struct entry *element)
{
    element->next = addOn;
    addOn->value = 400;
    addOn->next = (struct entry *) 0;
}

然而,一旦完成,我想检查是否有任何其他解决方案已在网上发布,以防我遗漏任何事情。

我找到了问题和回答HERE,并且存在很大的差异。

忽略值的打印格式的差异,您可以看到编写的代码要多得多,特别是在函数中。这是我的删除功能:

void removeEntry(struct entry *start)
{
    start->previous->next = start->next;
}

这是他们的:

void RemoveEntry(struct Entry *EntryToRemove)
{
    if (EntryToRemove->Previous != NULL)
    {
        EntryToRemove->Previous->Next = EntryToRemove->Next;
    }
    if (EntryToRemove->Next != NULL)
    {
        EntryToRemove->Next->Previous = EntryToRemove->Previous;
    }
    EntryToRemove->Previous = NULL;
    EntryToRemove->Next = NULL;
}

现在我可以看到有一个NULL检查,但除此之外,他们正在处理PreviousNext值,并为每个值都有一个if语句。

同样,您可以在此处查看我的insert功能:

void insertEntry(struct entry *addOn, struct entry *element)
{

    element->next = addOn;
    addOn->value = 400;
    addOn->next = (struct entry *) 0;
}

和他们的:

void InsertEntry(struct Entry *InsertPosition, struct Entry *EntryToInsert)
{
    EntryToInsert->Previous = InsertPosition->Previous;
    EntryToInsert->Next = InsertPosition;
    if (InsertPosition->Previous != NULL)
    {
        InsertPosition->Previous->Next = EntryToInsert;
    }
    InsertPosition->Previous = EntryToInsert;
}

请记住,我的代码完全符合我的目的,我的打印输出是:

100
200
300

100
300

100
300
400

你可以试着向我解释一下吗?我觉得自己像个白痴,因为我无法理解这一点。

这是他们的完整代码:

#include <stdio.h>vv

struct Entry
{
    int Value;
    struct Entry *Previous;
    struct Entry *Next;
};

void InsertEntry(struct Entry *InsertPosition, struct Entry *EntryToInsert);
void RemoveEntry(struct Entry *EntryToRemove);

int main()
{
    struct Entry N1, N2, N3, N4, N5, Insert, *Start = &N1;

    //set initial values
    N1.Value = 10;
    N2.Value = 20;
    N3.Value = 20;
    N4.Value = 30;
    N5.Value = 40;
    Insert.Value = 35;

    //link the list

    N1.Next = &N2;
    N2.Next = &N3;
    N3.Next = &N4;
    N4.Next = &N5;
    N5.Next = NULL;
    //Link again

    N1.Previous = NULL;
    N2.Previous = &N1;
    N3.Previous = &N2;
    N4.Previous = &N3;
    N5.Previous = &N4;

    InsertEntry(&N4, &Insert);
    RemoveEntry(&N2);

    //Display the Lists
    while (Start != (struct Entry *) 0)
    {
        printf("Previous: ");
        if (Start->Previous != NULL)
        {
            printf("%i", Start->Previous->Value);
        }
        else
        {
            printf("NULL");
        }
        printf(", Current: %i, Next: ", Start->Value);
        if (Start->Next != NULL)
        {
            printf("%i", Start->Next->Value);
        }
        else
        {
            printf("NULL");
        }
        printf("\n");
        Start = Start->Next;
    }

    return 0;
}

void InsertEntry(struct Entry *InsertPosition, struct Entry *EntryToInsert)
{
    EntryToInsert->Previous = InsertPosition->Previous;
    EntryToInsert->Next = InsertPosition;
    if (InsertPosition->Previous != NULL)
    {
        InsertPosition->Previous->Next = EntryToInsert;
    }
    InsertPosition->Previous = EntryToInsert;

}

void RemoveEntry(struct Entry *EntryToRemove)
{
    if (EntryToRemove->Previous != NULL)
    {
        EntryToRemove->Previous->Next = EntryToRemove->Next;
    }
    if (EntryToRemove->Next != NULL)
    {
        EntryToRemove->Next->Previous = EntryToRemove->Previous;
    }
    EntryToRemove->Previous = NULL;
    EntryToRemove->Next = NULL;
}

感谢您的时间。

2 个答案:

答案 0 :(得分:2)

代码不同,因为您的代码未成功实现双链表。例如,尝试在列表中间插入一个条目,然后从结尾打印到开头,你会发现链接的代码可以正常工作,但是你的链接代码没有。

答案 1 :(得分:2)

  

请记住,我的代码完全符合我的目的,我的打印输出是:....

这是新程序员所说的最强危险天真的最重要的事情。它绝对没有告诉我们。编程不是最终证明手段合理性的问题。你可以在计算器上按错按钮,得到正确的答案吗?

您的测试包括在列表中单向遍历。单链表将通过该测试。

您是否测试了反向遍历?这是单链表和双链表之间的所有关键区别 你是否测试过中间和前后的插入和移除?

周期怎么样?如果您将一个元素添加到列表中已经存在的列表中会发生什么?