插入到已排序位置的链表

发布于 2024-09-28 11:05:33 字数 2417 浏览 3 评论 0原文

我有一个与我不久前问过的问题非常相关的问题

放置一个立即在排序位置中插入值

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

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

编辑

我想我会采用前瞻性方法,这就是我到目前为止所做的。我陷入了如何保存前一个(键,值)的困境。这是到目前为止已完成的代码。 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);
      }      
   }  
}

I have question quite much related to this one I asked a while ago

place a value in the sorted position immediately

I wonder if you can use the same approach in that you step backward in a linked list to find the position it should be inserted into.

If it is possible how do you loop a linked list backward? I can't figure it out because it seems not possible since it should be a double linked listed then if I'm not wrong? Anyway I'm working with singly linked list.

EDIT

I think I'm going for the look forward approach, this is what I made so far. I'm stuck at that point in how I should save the previous (key, value). Here's the code so far of what's done. The for-loop is used to look for the position I want to insert to. And I have peek forward, which will break in case it reach the end.

OK so far, now I want to insert the value to the correct position. It is here I'm stuck. How should it be done? Now when I insert keys: 2, 1, 0, 3, it will only print out 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);
      }      
   }  
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

谁的新欢旧爱 2024-10-05 11:05:33

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

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

You can't traverse a singly-linked list backward, but you can keep a pointer to the last two elements you have seen instead of just one.

So, traverse the list from the front, and keep two pointers: current, and previous. If the element you are inserting is less than current, then update previous to point to it.

伪心 2024-10-05 11:05:33

不,单链表不能向后移动。

No a singly linked list cannot go backwards.

兔姬 2024-10-05 11:05:33

这是我对你所问问题的理解:当你在单链表中搜索插入位置时,你会发现你已经走得太远了,那么如何返回呢?

嗯,主要有两种解决方案:

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

  • 确保有一个人工尾节点(这样你总是有一个真正的下一个节点),并且没有其他“外部”指针指向列表而不是您的搜索指针。将新节点插入到具有更高值的节点之后。交换两个节点的内容。

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

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

干杯&呵呵,,

Here's my understanding of what you're asking: when you search for an insert position in a singly linked list you find it by discovering that you've gone one node too far, then, how to go back?

Well, there are two main solutions:

  • peek one node ahead while searching (a different viewpoint of the same idea is to keep a "trailing" pointer), or

  • make sure that there's an artifical tail-node (so that you always have a real next node), and that there are no other "external" pointers into the list than your search pointer. Insert your new node after the node with higher value. Swap the contents of the two nodes.

The second solution is a little brittle because of the assumption of no other "external" pointers into the list. But it's sort of ingenious. I learned it from Donald Knuth's "The Art of Computer Programming".

Alternatively to these singly linked list solutions, you can just double-link your list.

Cheers & hth.,

另类 2024-10-05 11:05:33

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

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

You can use recursion to traverse a singly linked list backwards.

void traverse_backwards(NODE node)
{
    if (node->next != null && !node->is_marked)
    {
        node->is_marked = 1;
        traverse_backwards(node->next);
    }
    else
    {
        // logic goes here
    }
}
不疑不惑不回忆 2024-10-05 11:05:33

举个例子更容易

10 -> 20 -> 30 -> NULL

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

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

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

  1. create newNode with newNode->key = insertKeynewNode->value = insertValue

  2. currentNodenextNode 之间“插入”newNode代码>通过做

    2.1 currentNode->next = newNode

    2.2 newNode->next = nextNode

Its easier to take an example

10 -> 20 -> 30 -> NULL

Traverse the list with two pointers: (i) currentNode and (ii) nextNode.

Start with currentNode = NULL and nextNode = <10>. Move both of them forward in a loop as long as nextNode->key < insertkey is true.

Upon exit from loop (example: for insertKey == 25, currentNode = <20>, nextNode = <30>):

  1. create newNode with newNode->key = insertKey and newNode->value = insertValue

  2. "Insert" newNode between currentNode and nextNode by doing

    2.1 currentNode->next = newNode

    2.2 newNode->next = nextNode

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文