У меня проблема с какой-то функцией / алгоритмом, и я надеюсь, что вы, ребята, сможете мне помочь. Задача состоит в том, чтобы написать функцию, которая удалит элемент, который находится сразу после самого высокого элемента (наибольшее значение) в одном связанном круговом списке. Я пытался нарисовать это так, чтобы это имело больше смысла для меня, но это все еще выглядит как темное искусство, но мне удалось придумать такую функцию:
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 — самый большой, в последнем цикле 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
уменьшить цикл на 2 шага.
- 1)
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
}
ДОБАВЛЕНО № 1 >>>>
Ошибка 3 — случай if (index == 0)
это невозможно
Попробуйте удалить первый узел кругового связного списка, когда
Максимальное размещение в последнем узле невозможно.
index = 0;
возможно только тогда, когда if (counter == index)
, Но в do-while, просто после сохранения позиции максимума в 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;
}
Затем разрешите цикл while, когда (index == counter)
с:
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;
ДОБАВЛЕНО N ° 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;
Других решений пока нет …