如何删除C++循环列表中找到的最高元素旁边的元素
Posted
技术标签:
【中文标题】如何删除C++循环列表中找到的最高元素旁边的元素【英文标题】:How to delete element next to the highest found element in the circular list in C++ 【发布时间】:2017-03-08 19:02:21 【问题描述】:我遇到了一些函数/算法的问题,希望你们能帮助我。任务是编写一个函数,该函数将删除单链循环列表中最高元素(最大值)之后的元素。我一直在尝试画这个,所以这对我来说更有意义,但它看起来仍然像黑暗艺术,但我设法想出了这样的功能:
struct node
node * next;
double data;
;
void Insert_node(node * & head, double v)
node * p = new node;
p->data = v;
if(head)
p->next = head->next;
head->next = p;
else p->next = p;
head = p;
void Delete_After_Max(node* & head)
node * tmp=head;
int counter=0,index=0;
double maximum=0;
if(tmp) // checking if the list is not empty
do
if(tmp->data>maximum)
maximum=tmp->data;
index=counter+1;
counter++;
tmp=tmp->next;
while(tmp!=head);
cout<<"Biggest value on the list: "<<maximum<<endl;
cout<<"licznik:"<<counter<<" "<<"indeks: "<<index<<endl;
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)
index=counter;
// checking if the highest element was somewhere else
node *tmp3=NULL;
int position=0;
if((index>0)&& (index<=counter))
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;
你觉得这个算法对吗?我不确定我的想法是否正确,所以代码可能完全错误:/
首先,我计算列表中的所有元素,找到最高的那个和它的索引,然后我可以使用它通过增加索引来删除之后的元素,对吗?我认为现在还可以,但是在那之后对我来说变得更难了,如果最大值是最后一个元素,我必须删除第一个元素,然后将最后一个元素与第二个元素“连接”?但是我不知道循环列表是否可以,所以请有人给我一个提示我做错了什么吗? ;)
我再次检查了它,它可以编译但它不能正常工作,我仍然不知道为什么,以及如何去做。我找不到任何可以基于的类似问题,任何形式的帮助都将不胜感激,我是新手,这就是为什么有这么多错误...
【问题讨论】:
【参考方案1】:在所提出的算法中,小错误会导致错误的结果。
错误 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;
【讨论】:
好的,我修复了您指出的错误,但是当我尝试运行整个代码时,它会崩溃..但是代码的其他部分可能存在问题,但是现在我只需要这个算法是正确的;)。所以现在我修复了错误,算法假设可以正常工作?或者我错过了一些案例,但仍然没有任何意义? 我处理了代码,但是将位置设置为 1,而不是像你说的那样设置为 0,并且它正在工作:元素数量减少 1,并且在我之后不显示最大元素之后的元素使用这个函数,但是有一个问题——如果最大值在最后一个元素,它就会崩溃,我不知道如何解决这个问题 @WojtekMika,为了确保函数Delete_After_Max()
,有必要知道如何在循环链表中添加/插入数据。您能否编辑问题并添加struct node
定义和insert()
函数? 注意:我创建了自己的简单insert()
函数,但不确定它是否与您的匹配!!!
我编辑了评论,我认为插入功能正常工作,删除功能几乎正常工作,除了最高元素是列表中“最后一个”的这种情况,但我没有'不知道如何解决它,因为它应该被圈出列表......如果最后一个元素是最高的,第一个应该被删除,但它在我的代码中不起作用
我已经添加了案例的解决方案'最高元素是列表中的“最后一个”'。以上是关于如何删除C++循环列表中找到的最高元素旁边的元素的主要内容,如果未能解决你的问题,请参考以下文章