Я хочу использовать перегрузку оператора нижнего индекса в списке ссылок, но каждый раз, когда он выдает ошибку сегментации (сбрасывается ядро) ОШИБКА! МОЯ ЗАДАЧА: (Оператор перегрузки []. Используйте цикл for в main, чтобы отобразить его.) Я ТАКЖЕ ПРЕДОСТАВЛЯЮ ССЫЛКУ НА ЗАДАЧУ НИЖЕ //ссылка на задачу [ССЫЛКА НА ЗАДАНИЕ] https://anonymfile.com/r1XKK/dsa-a3.pdf
//МОЙ КОД:
#include <iostream>
using namespace std;
class LinkedList
{
private:
class Node
{
public:
int data;
Node * next;
Node(int data)
{
this->data = data;
this->next = NULL;
}
};
public:
Node *head;
LinkedList(){
head = NULL;
}
//Write a copy constructor. Also copy must be deep.
LinkedList(LinkedList& S)
{
head = S.head;
}
//Overload [] operator. Use for loop in main to display it.
void operator[](int i) {
head->data = i;
}
void InsertAtEnd(int data){
if (head == NULL)
{
head = new Node(data);
return;
}
Node * temp = head;
while (temp->next != NULL)
{
temp = temp->next;
}
temp->next = new Node(data);
}
void Insert(int d1, int d2)//Add the node of data d2 after the node with data d1. If d2 is not available add it to the end.
{
if (head == NULL)
{
Node * n = new Node(d2);
n->next = head;
head = n;
return;
}
Node * temp = head;
while (temp != NULL)
{
if (temp->data == d1)
{
Node * temp1 = temp->next;
temp->next = new Node(d2);
temp->next->next = temp1;
}
temp = temp->next;
}
}
void Delete(int data){
Node * todelete;
if (head->data == data){
todelete = head;
head = head->next;
free(todelete);
return;
}
Node *temp = head;
while(temp->next != NULL){
if (temp->next->data == data){
todelete = temp->next;
temp->next = temp->next->next;
free(todelete);
break;
}
temp = temp->next;
}
} // Deletes a node with data.
int getSize(){
Node * temp = head;
int size = 0;
while(temp != NULL){
temp = temp->next;
size++;
}
return size;
} //returns the count of elements in the list
bool IsEmpty(){
if (head == NULL){
return true;
}
else{
return false;
}
} //Returns true if empty.
void Merge(Node * list){
//merge
Node * temp = head;
while(temp != NULL){
if (temp->next == NULL and list != NULL){
temp->next = list;
break;
}
temp = temp->next;
}
//DISPLAY
while(head!=NULL){
cout<<head->data<<"->";
head=head->next;
}
cout<<"NULL"<<endl;
} //Merges the to the calling class.
void Erase(){
Node * erase;
while(head!= NULL){
erase = head;
head = head->next;
head = NULL;
}
free(erase);
} //Deletes every node in an array.
void SelectiveErase(int num) //Find num and delete everything after num.
{
Node * temp = head;
Node * todelete;
while(temp != NULL){
if (temp->data == num){
Node * erase = temp->next;
while(temp->next != NULL){
erase = temp->next;
temp->next = temp->next->next;
temp->next = NULL;
}
free(erase);
break;
}
temp = temp->next;
}
}
int FindNCount(int find)//Find and return count of all occurrence.
{
int counter = 0;
bool flag = false;
Node * temp = head;
while(temp->data!= find){
temp = temp->next;
counter++;
}
return counter;
}
int RemoveDuplicate(int find)//Find and remove every duplicate element in the list. Make //elements unique.
{
Node * temp = head;
Node *temp1;
while(temp != NULL){
temp1 = temp;
while(temp1->next != NULL){
if (temp->data == temp1->next->data and temp->data == find and temp1->next->data == find){
Node *todelete = temp1->next;
temp1->next = temp1->next->next;
free(todelete);
}
else{
temp1 = temp1->next;
}
}
temp = temp->next;
}
return find;
}
void FindNReplace(int find, int data)//Find and replace all occurrence recursively.
{
Node * temp = head;
while(temp != NULL){
if (temp->data == find){
temp->data = data;
break;
}
temp = temp->next;
}
}
void Display(){
static Node * temp= head;
if (temp == NULL){ cout << "NULL" << endl; return;}
cout << temp->data<<"->";
temp = temp->next;
Display();
}
};
void Swap() // swap the contents of one list with another list of same type and size. Also write parameter
{
LinkedList L,L1;
cout<<"AFTER SWAPING THE VALUE OF FIRST LIST \n";
while(L.head != NULL && L1.head != NULL){
int temp = L.head->data;
L.head->data = L1.head->data;
L1.head->data = temp;
cout<<L.head->data<<"\n";
L.head = L.head->next;
L1.head = L1.head->next;
}
cout<<endl;
}
int main()
{
// You must call Display function after every function.
LinkedList L{};
L[23];
// LinkedList L1;
// L1.InsertAtEnd(5);
// L1.InsertAtEnd(6);
//L.Erase();
// cout<<L.FindNCount(1)<<endl;
//L.SelectiveErase(2);
//L.Display();
//L.Merge(L1.head);
//L.RemoveDuplicate(2);
//L.Display();
//Swap();
return 0;
}
head = NULL;
в вашем коде вы никогда не создаете Node
. head — это nullptr, а затем head->data
не определено. Вам нужен узел, прежде чем вы сможете получить доступ к его значению
И как вы собираетесь получить доступ к узлу номер 23 в пустом списке?
вам также необходимо прочитать это en.cppreference.com/w/cpp/language/rule_of_three
На самом деле этот код показывает, что у вас есть серьезные пробелы в понимании. Предполагается, что оператор [] получает значение из списка, он не должен устанавливать элемент в списке и не должен cout <<
значения (это происходит в main). Также head = S.head;
— это не глубокая копия, а наоборот, поверхностная копия.
На самом деле вы не можете выполнить эту задачу, пока у вас не будет работающего связанного списка, в который вы можете добавлять узлы, к которому вы позже получите доступ с помощью operator[]
. В этом вопросе нет доказательств того, что у вас есть рабочий связанный список. Итак, это ваша первая задача, написать какой-нибудь работающий код связанного списка. Затем попробуйте задачу operator[].
Семантика оператора индекса такова: «дайте мне n-й элемент в контейнере». Это может работать, но доступ к элементам списка через него будет медленным. Вам нужно будет каждый раз начинать с начала списка, а затем переходить к пункту n-th
. В основном изменение сложности доступа с O (1) до O (n). Так что нет, не очень хорошая идея для списков.
Обычно подпись оператора DataType& operator[](size_t index);
или DataType const& operator[](size_t index) const;
. Оператор редко имеет побочные эффекты для структур, подобных спискам. Ваша реализация оператора установит индекс как значение данных первого элемента, если он есть, и выведет что-нибудь на консоль. Это не то, чего можно ожидать от оператора индекса списка.
По этой же причине в списке C++ en.cppreference.com/w/cpp/container/list нет оператора индекса. И std::list
— это то, что вы должны использовать, если только вы не выполняете упражнение для класса структур данных.
Кстати, для C++ я настоятельно рекомендую использовать ключевое слово nullptr
вместо макроса NULL
, поскольку nullptr
не может быть неявно преобразовано в int
, которое NULL
может зависеть от стандартной библиотеки.
@PepijnKramer: для этого могут быть варианты использования. Контейнер, который будет содержать только небольшое количество объектов, с большим количеством вставок и удалений и несколькими прямыми доступами. Но я признаю, что это действительно крайний случай ;-). Тем не менее, это может быть интересной домашней работой для изучения пользовательских контейнеров, и OP еще многому предстоит научиться...
@SergeBallesta О, конечно, изучение того, как реализовать оператор индексирования, является хорошим вариантом использования (чтобы узнать о перегрузке оператора, какой семантике ожидается от оператора индексирования и т. д., что то, что кажется хорошим для клиентского кода, может иметь непредвиденные последствия для производительности и т. д.) . Я думаю, что OP может многому научиться сегодня :)
между прочим, даже если ваш LinkedList
будет в порядке, код в main
будет неправильным. Если пользователь пытается получить доступ к элементу в пустом контейнере, это не ошибка контейнеров. Обычно проверка границ не выполняется, а доступ за пределами границ не определен.
Перегрузка оператора индекса должна что-то вернуть. Назначение выглядит немного расплывчатым, но я надеюсь, что это исправит:
//Overload [] operator. Use for loop in main to display it.
Node* operator[](int i) {
Node* nodePtr = head;
int counter = 0;
while (nodePtr != NULL && counter != i) {
nodePtr = nodePtr->next;
counter++;
}
return nodePtr;
}
Если вы думаете о векторе или даже о массиве, что на самом деле делает оператор нижнего индекса? Какова ваша настоящая «задача»? Пожалуйста, скопируйте и вставьте полный текст задания или упражнения в свой вопрос.