在双向链表中添加重复项(字符串)

时间:2015-06-30 03:14:09

标签: c doubly-linked-list

我目前正在计算双链表的实现。听起来很奇怪,我 想要 重复的项目添加到我的链接列表中。 我按排序顺序将newNode添加到列表中。

以下功能不会添加重复节点。

struct Node
{
    char name[42];
    struct Node *next;
    struct Node *prev;
};

void addSorted(struct Node **head, struct Node *newNode)
{
    struct Node* current;
    // Special case for the head end
    if ((*head == NULL) || strcmp((*head)->name, newNode->name) >= 0)
    {
        newNode->next = *head;
        *head = newNode;
    }
    else
    {
        // Locate the Node before the point of insertion
        current = *head;
        while (current->next != NULL &&
                strcmp(current->next->name, newNode->name) <= 0)
        {
            current = current->next;
        }
        newNode->next = current->next;
        current->next = newNode;
    }
}

struct Node* GetNewNode(char *name)
{
    struct Node* newNode = malloc(sizeof (struct Node));

    strcpy(newNode->name, name);
    newNode->prev = NULL;
    newNode->next = NULL;

    return newNode;
}

int main(void)
{
    // Some Irrelevant Code
    if (strncmp(operator, "a", 1) == 0)
    {
        temp = GetNewNode(name);

        addSorted(&head, temp);
    }
 }

3 个答案:

答案 0 :(得分:1)

我认为主要的一点是你没有处理 prev 指针以及第一个if,应该有两种情况,

if(*head==NULL)
{
 *head=newNode;
}
else if(strcmp((*head)->name, newNode->name) >= 0)
{
 (*head)->prev=newNode;//ADD THIS LINE
 newNode->next = *head;
 *head = newNode;
}

在else条件下进行以下更改

newNode->next = current->next;
current->next->prev = newNode;//CHANGE HERE
current->next=newNode;//ADD THIS LINE
newNode->prev=current;//ADD THIS LINE

答案 1 :(得分:0)

除了已经讨论过的prev指针管理器之外,还有一些其他方面需要您解决问题。首先,明智的做法是使用define来设置静态name数组的大小(这将成为验证name大小的必要条件):

#define MAXN

struct Node
{
    char name[MAXN];    /* use a define for static allocation size */
    struct Node *next;
    struct Node *prev;
};

这会导致GetNewNode中的两个问题。首先,您需要验证内存分配:

    struct Node* newNode = malloc(sizeof (struct Node));

    if (!newNode) { /* validate all memory allocations */
        fprintf (stderr, "%s() memory allocation failed.\n", __func__);
        exit (EXIT_FAILURE);
    }

然后,您还必须验证name的长度,以防止在name > 41 chars之后写入数组末尾:

    size_t namelen = strlen (name);

    if ( namelen > MAXN - 1) { /* validate string length */
        fprintf (stderr, "%s() name length (%zu) exceeds %d .\n", 
                 __func__, namelen, MAXN);
        return NULL;
    }

注意:使用define设置name的长度,您可以使用定义MAXL作为长度验证测试。

接下来,在GetNewNode中验证name的长度并返回NULL - 您现在必须处理main()中的返回并同时为{{提供声明1}}:

head

如果您的目的是创建循环列表,那么您必须测试几个附加条件,并在int main (void) { struct Node *head = NULL; /* head must be declared */ if (strncmp(operator, "a", 1) == 0) { temp = GetNewNode(name); if (temp) /* validate return */ addSorted(&head, temp); } } 中做出相应的响应。具体来说,您必须(1)在addSorted时创建列表。

如果您之前的陈述*head = NULL是正确的,那么您必须(2)在列表自我参照时考虑条件(即只有一个节点存在,指的是自身)。

您还有两个条件需要测试(3)newNode->next = *head; *head = newNode;是否在当前newNode->name之前排序,您必须在其中插入(*head)->name作为新的第一个节点在列表中;最后(4)newNode在当前newNode->name之后排序的情况。

即使使用线性头/尾列表,您也需要同时解决(3)&amp; (4)以上。如果您还有其他问题,请与我们联系。

答案 2 :(得分:-2)

使用双向链表,最好先找到需要插入的位置。

// pseudo code
current = head;
while (current) 
{
    if ( strcmp( name, current -> name) ... )  // your logic for your sort order
    {

    }
    current = current->next;
}

找到要插入的地点后,如果要将项目插入列表中,则需要处理四个案例。您必须处理头部/尾部变化以及向内和向外指向或根据需要处于空值。

  • 添加到一个完全空的列表(头部和尾部指向记录,prev和next为null)
  • 添加到前面(head获取新值,新记录prev为null),
  • 添加到结尾(tail获取新值,新记录接下来为null)
  • 添加到中间(头/尾不变)