繁体   English   中英

插入到排序位置的链表

[英]insert to sorted position linked list

我有一个问题与我刚才问过的问题有关

立即在排序位置放置一个值

我想知道您是否可以使用相同的方法,即在链接列表中向后退一步以查找应插入的位置。

如果有可能,如何将链表向后循环? 我无法弄清楚,因为似乎不可能,因为它应该是列出的双重链接,那么如果我没记错的话? 无论如何,我正在使用单链表。

编辑

我想我正在寻找一种前瞻性的方法,这就是我到目前为止所做的。 在这一点上,我被困在如何保存上一个(键,值)的位置上。 到目前为止,这是完成的代码。 for循环用于查找要插入的位置。 我向前看,万一到达终点,它将打破。

到目前为止,还可以,现在我想将值插入正确的位置。 在这里我被卡住了。 应该怎么做? 现在,当我插入钥匙: 2, 1, 0, 3 ,只会打印出1, 3

struct my_list
{
  /* a pointer to the first element of the list */
  struct list_link* first;
};

struct list_link
{
   int key;                // identifies the data
   double value;           // the data stored
   struct list_link* next; // a pointer to the next data
};

struct list_link* create(int key, double value, struct list_link* next)
{
   // creates the node;
   struct list_link * new_link;
   new_link = new struct list_link;

   // add values to the node;
   new_link->key = key;
   new_link->value = value;
   new_link->next = next;

   return new_link; // Replace this, it is just to be able to compile this file
}

void list_insert(struct my_list* my_this, int key, double value)
{
   if(my_this->first == NULL)   // add if list empty
      my_this->first = create(key, value, my_this->first);   
   else
   {      
      struct my_list* curr;
      struct my_list* prev;         
      struct my_list start;

      start.first = my_this->first;
      curr = my_this;

      cout << "Too be appended: ";
      cout << key << " " << value << endl;
      for(curr->first = my_this->first; 
          key > curr->first->key; 
          curr->first = curr->first->next)
      {
         if(curr->first->next == NULL) //peek at front if empty
            break;
      }
      cout << "append here " << key << " > " << 
          curr->first->key << endl << endl;
      //perform some surgery
      if(curr->first->next == NULL)
      {     
         curr->first->next = create(key, value, my_this->first->next);
      }
      else
      {       
         curr->first = start.first; //move back to start of list
         my_this->first = create(key, value, my_this->first);
      }      
   }  
}

您不能向后遍历单链接列表,但是可以保持指向您看到的最后两个元素的指针,而不仅仅是一个。

因此,从头开始遍历列表,并保留两个指针:当前指针和前一个指针。 如果您要插入的元素小于当前元素,则更新之前的内容以指向它。

没有一个单链列表不能向后移动。

这就是我对您要问的问题的理解:当您在单链列表中搜索插入位置时,通过发现您离一个节点太远而找到了该位置,然后如何返回?

好吧,有两个主要解决方案:

  • 在搜索时偷看一个节点(相同想法的不同观点是保持“尾随”指针),或者

  • 确保有一个人为的尾节点(这样,您始终会有一个真正的下一个节点),并且除了搜索指针外,列表中没有其他“外部”指针。 在值较高的节点之后插入新节点。 交换两个节点的内容。

第二种解决方案有些脆弱,因为假定列表中没有其他“外部”指针。 但这有点巧妙。 我是从Donald Knuth的“计算机编程艺术”中学到的。

除了这些单链列表解决方案之外,您还可以双链列表。

干杯,……

您可以使用递归向后遍历单个链接列表。

void traverse_backwards(NODE node)
{
    if (node->next != null && !node->is_marked)
    {
        node->is_marked = 1;
        traverse_backwards(node->next);
    }
    else
    {
        // logic goes here
    }
}

举个例子比较容易

10 -> 20 -> 30 -> NULL

用两个指针遍历列表:(i) currentNode和(ii) nextNode

currentNode = NULLnextNode = <10> 只要nextNode->key < insertkey为true,则将它们向前循环移动。

从循环退出时(例如:对于insertKey == 25, currentNode = <20>, nextNode = <30> ):

  1. 使用newNode->key = insertKeynewNode->value = insertValue创建newNode

  2. 通过执行以下操作在currentNodenextNode之间“插入” newNode

    2.1 currentNode->next = newNode

    2.2 newNode->next = nextNode

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM