在所提出的算法中,小错误会导致错误的结果。
错误 1 - 最大的,在最后一个 while 循环中,tmp2 未初始化。
初始化tmp2 = head 而不是tmp3 = head;。
tmp2 = head; // initialize tmp2
while (position<index - 1)
{
tmp2 = tmp2->next;
position++;
}
tmp3 = tmp2->next;
错误 2 - 以 position 开头等于 1 会过早停止循环。
使用第一个 position = 1 和 while 条件 (position < index
- 1) 将循环减少 2 步。
int position = 0;
拼写错误 - 在if (index == 0) 条件下,缺少半列。
行代码head = head->next 不以; 结尾。
在if (index == 0) 条件下,要么使用return 退出函数,要么通过在else { ... } 条件中插入最后一部分来防止执行意外操作。
if (index == 0)
{
tmp2 = head;
head = head->next;
delete tmp2;
// EXIT by return
}
增加了 N°1>>>>
错误 3 - if (index == 0) 的情况是不可能的
尝试删除循环链表的第一个节点
最大值放在最后一个节点是不可能的。
- 值
index = 0; 仅当if (counter == index) 时才可能。但在执行过程中,在将最大值的位置存储在 index = counter; 之后,counter 会增加 counter++;。
修改如下:
if (counter == (index+1)) // detecting the last position
index = 0; //if last element is the maximum, first one will be deleted
else
index++; // incrementing to get index of the next element after maximum
- 但是要删除第一个节点,
if (index == 0) 的建议算法不起作用,因为需要存储前一个节点。
解决方案 - 最好的解决方案是通过执行以下更改来强制最后一个 while 循环再继续执行一步:
if (index == 0)
{
index = counter;
}
然后在(index == counter) with 时允许while循环:
if ((index>0) && (index<=counter)) // allow for the last
{
tmp2 = head;
while (position<index - 1)
并且在删除tmp3节点之前,修改head时tmp3 == head:
tmp3 = tmp2->next;
tmp2->next = tmp3->next;
if (head==tmp3) { // when the node to delete is the head
head = head->next; // shift head to the next node
}
delete tmp3;
新增第 2 个>>>>
输出 - 这是使用建议的值列表时获得的结果。
第一个元素6是被删除的(最后一个元素的下一个元素
18 在循环链表中)。
[ 6, 9, 13, 12, 1, 10, 15, 4, 6, 18, ].
Biggest value on the list: 18
[ 9, 13, 12, 1, 10, 15, 4, 6, 18, ].
新增第3号>>>>
这里是函数Delete_After_Max()的完整源代码:
void Delete_After_Max(node* & head)
{
node * tmp = head;
int counter = 0, index = 0;
double maximum = -1;
if (tmp) // checking if the list is not empty
{
do
{
if (tmp->data>maximum)
{
maximum = tmp->data;
index = counter;
}
counter++;
tmp = tmp->next;
} while (tmp != head);
}
std::cout << "Biggest value on the list: " << maximum << "\n";
if (counter == (index+1))
index = 0; //if last element is the maximum, first one will be deleted
else
index++; // incrementing to get index of the next element after maximum
node *tmp2 = NULL;
//checking if the highest element was last(then we delete first one)
if (index == 0)
{
tmp2 = head;
std::cout << tmp2->data << ", ";
index = counter;
//head = head->next;
//delete tmp2;
// EXIT
}
// checking if the highest element was somewhere else
node *tmp3 = NULL;
int position = 0; // ERROR 1;
// if ((index>0) && (index<counter))
if ((index>0) && (index<=counter))
{
// ERROR tmp3 = head;
tmp2 = head;
while (position<index - 1)
{
tmp2 = tmp2->next;
position++;
}
tmp3 = tmp2->next;
tmp2->next = tmp3->next;
if (head==tmp3) {
head = head->next;
}
delete tmp3;
}
}
增加了 N°4>>>>
在更新函数Delete_After_Max()下方显示的逻辑删除最大值以下的节点是错误的。
bool Delete_After_Max(node* & head)
{
node *maxi=Find_Maximum(head);
std::cout << "Biggest value on the list: " << maxi->data << "\n";
if(!Is_Empty) // !Is_Empty because this function is not working properly so i had to negate it until i find out why ;)
{
cout<<"the list is empty";
return false;
}
else
{
node *tmp3=NULL;
node *tmp2=maxi->next;
tmp3=tmp2->next;
tmp2->next=tmp3->next;
if (head==tmp3) {
head = head->next;
}
delete tmp3;
cout<<"one element deleted";
return true;
}
}
- 如果
maxi指向的节点具有最大值,则要删除的节点是maxi->next(而不是调用tmp2,我们将它称为node_to_delete)。
- 在删除
node_to_delete之前,需要将节点maxi与node_to_delete之后的节点连接起来(而不是调用tmp3,我们将其称为node_after_delete)。
- 如果
node_to_delete 是head,则需要在删除前将head 更新为下一个节点。
那么,函数中新的删除部分就变成了:
// Step 1
node *node_to_delete = maxi->next;
// Step 2
node *node_after_delete = node_to_delete->next;
maxi->next = node_after_delete;
// Step 3
if (node_to_delete == head) {
head = head->next;
}
delete node_to_delete;
所以,Delete_After_Max() 函数中的逻辑错误是:
- 节点
maxi 和节点 node_after_delete (tmp3) 之间的连接不良 ==> maxi->next=tmp3; 而不是 tmp2->next=tmp3->next;,
- 节点
node_to_delete (tmp2) ==> 的错误定义if (head==tmp2) 和delete tmp2; 而不是if (head==tmp3) 和delete tmp3;