[英]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 = NULL
和nextNode = <10>
。 只要nextNode->key < insertkey
为true,则将它们向前循环移动。
从循环退出时(例如:对于insertKey == 25, currentNode = <20>, nextNode = <30>
):
使用newNode->key = insertKey
和newNode->value = insertValue
创建newNode
通过执行以下操作在currentNode
和nextNode
之间“插入” newNode
2.1 currentNode->next = newNode
2.2 newNode->next = nextNode
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.