【问题标题】:inserting in singly linked list in ascending order以升序插入单链表
【发布时间】:2014-10-14 03:07:08
【问题描述】:

假设我有一个按升序排列的单链元素列表,如下所示:

A->B->D->E

我想在 B 和 D 之间插入 C。 我知道如何将 C 指向 D,但我不知道如何将 B 指向 C,因为链表不跟踪 prev 节点。

【问题讨论】:

    标签: c linked-list


    【解决方案1】:

    当您向下扫描节点列表时,您必须保留两个指针:一个指向您感兴趣的当前节点,另一个指向前一个节点。

    【讨论】:

      【解决方案2】:

      一个可能的实现如下:

      struct node {
          int value;
          struct node *next;
      };
      
      void sorted_insert(struct node **head, struct node *element) {
          // Is the linked list empty?
          if (*head == NULL) {
              element->next = NULL;
              *head = element;
              return;
          }
      
          // Should we insert at the head of the linked list
          if (element->value < (*head)->value) {
              element->next = *head;
              *head = element;
              return;
          }
      
          // Otherwise, find the last element that is smaller than this node
          struct node *needle = *head;
          while (true) {
              if (needle->next == NULL)
                  break;
              if (element->value < needle->next->value)
                  break;
              needle = needle->next;
          }
      
          // Insert the element
          element->next = needle->next;
          needle->next = element;
          return;
      }
      

      【讨论】:

        【解决方案3】:

        您不需要将 B 指向 C,或者维护指向前一个元素的指针。一种方法是:

        1. 到节点 D 的步骤

        2. malloc()一个新节点

        3. 将数据和next成员从节点D复制到新节点

        4. 将节点 C 的数据复制到现有节点 D(现在成为节点 C)

        5. 将旧节点D的next成员指向新节点。

        例如,排除在列表头部插入的可能性:

        void insert(struct node * head, const int data, const size_t before)
        {
            assert(before > 0);
        
            struct node * node = head;
        
            while ( before-- && node ) {
                node = node->next;
            }
        
            if ( !node ) {
                fprintf(stderr, "index out of range\n");
                exit(EXIT_FAILURE);
            }
        
            struct node * new_node = malloc(sizeof *new_node);
            if ( !new_node ) {
                perror("couldn't allocate memory for node");
                exit(EXIT_FAILURE);
            }
        
            new_node->data = node->data;
            new_node->next = node->next;
        
            node->next = new_node;
            node->data = data;
        }
        

        【讨论】:

        • 这假设复制节点内容(有效负载)是一个微不足道且允许的操作。
        • @DwayneTowell:创建任何新节点也是如此。
        • 这在要插入的节点是“预构建”的环境中很重要。
        • @DwayneTowell:即使那样,你也可以存储一个指向它的指针,而且指针显然是可以简单复制的。
        【解决方案4】:

        为什么在遍历列表时不跟踪“上一个”节点?请原谅任何语法缺陷,因为我没有编译这个,但这应该给你的想法。

        struct node {
          char name[ 10 ];
          struct node *next;
        };
        
        struct list {
          struct node *head;
        };
        
        void insert_C(struct list *list) {
        
          struct node *new_node = malloc(sizeof(struct node));
          if( new_node == NULL ) {
            /* Error handling */
          }
        
          strcpy(new_node->name, "C");
        
          struct node *pnode;
          struct node *prev_node = NULL;
          for( pnode = list->head; pnode->next != null; pnode = pnode->next ) {
        
            if( !strcmp(pnode->name, "D") ) {
              if( prev_node == NULL ) {
                /* The 'C' node is going to be the new head. */
                new_node->next = list->head;
                list->head = new_node;
              }
              else {
                prev_node->next = new_node;
                new_node->next = pnode;
              }
        
              break;
            } 
        
            /* Remember this node for the next loop iteration! */
            prev_node = pnode;
          }
        
        }
        

        【讨论】:

          猜你喜欢
          • 2014-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-13
          • 2018-07-18
          • 1970-01-01
          相关资源
          最近更新 更多