将节点插入到C中的已排序链接列表中

时间:2016-11-25 19:48:05

标签: c linked-list

我需要将一个节点插入到已排序的链表中。该列表有一个虚拟节点。

.find('.infoCatcher')

这会在列表末尾插入一个节点。我理解添加排序的逻辑。您向前看下一个节点,如果新节点小于下一个节点,则将新节点指向下一个节点,将前一个节点指向新节点。有人可以帮助我在代码中实现这一点。这是我到目前为止所做的,但不起作用。

void add(Node **nodeArray, int setNumber) {
    char userString[5];
    Node *head = nodeArray[setNumber];      /* head pointer to first element of array (dummy) */
    Node *newNode = malloc(sizeof(Node));   /* new node to be added to array */
    Node *tmp = head;

    printf("Please enter some data: ");
    scanf("%s", userString);

    strncpy(newNode->data, userString, DATA_SIZE);  /* copies string entered by the user to data field of new node */
    newNode->next = NULL;   /* initializes next field of new node to NULL */



    while (tmp->next) 
        tmp = tmp->next;        /* points head to next element in list */
    tmp->next = newNode;    /* adds element to list */
}

以下是比较功能:

if (!tmp->next)
    tmp->next = newNode;
else {
    while (tmp->next) {
        if (strcmpa((tmp->next)->data, newNode->data) < 0) {
            newNode->next = tmp->next;
            tmp->next = newNode;
        } //else if (strcmpa((tmp->next)->data, newNode->data) > 0) {
            //tmp->next = newNode;
        //}
        tmp = tmp->next;
    }
}

1 个答案:

答案 0 :(得分:1)

你几乎就在那里,但tmp->next应该被重定向到newNode本身,而不是newNode->next。实际上,这是一个无操作,因为在该命令发生时,newNode->nexttmp->next,而你正在重新分配已存在的值。

你想要的是tmp,指向X,而是指向next,而后者只指向X。所以,正式来说,

X = tmp->next;
tmp->next = newNode;
newNode->next = X;

可以压缩到

newNode->next = tmp->next; /* using the X where originally stored */
tmp->next = newNode; /* rewriting that memory has to wait till now */

更新:上述代码在newNode之后链接tmp(因为我认为这就是您所需要的)。但是在排序列表中,您会发现需要在节点之后显示的第一个tmp,因此您需要先执行此操作。这带来了两个问题:

  1. 您需要修改 tmp之前的项目,因为新节点会去那里,所以您需要再保留一个变量,

  2. 有时您需要将新节点放在最初的节点上,该节点没有上一个节点。

  3. 在正面,上面还优雅地处理!tmp->next(最后插入),这样你就不需要另一个分支。

    看起来像

    Node* head = (whatever);
    Node* prev = NULL;
    Node* tmp;
    
    for(tmp = head; tmp && strcmpa(tmp->data, newNode->data) < 0; tmp = tmp->next) {
        prev = tmp;
    }
    
    /* now tmp points to the first larger node or to NULL and prev is its preceding node.
     * If there's none (if the head is already larger) then prev = NULL. */
    
    if(prev == NULL) {
        newNode->next = head;
        head = newNode; /* Don't forget to update this in the array where you took head from! */
    } else {
        newNode->next = prev->next;
        prev->next = newNode;
    }
    

    如果headNULL并且创建包含单个条目的链接列表,则此方法也有效。

    这专注于插入。关于其余代码(最初发布为评论):

    • 如果您在无限制userString %s上超出scanf缓冲区,程序将失败。设定限额。

    • 如果有限制,则不需要不安全的strncpy。使用正常的strcpy来保证它将终止你的字符串。

    • 您的strcmpa看起来不错。但请确保tolower()使用'\0'的输入执行您期望的操作。这会正确地比较字符串:

      char toLower(char in) { 
        if(in >= 'A' && in <= 'Z')
          return in + 'a' - 'A';
        else
          return in;
      }