Не выдает значения запрашиваемого списка
я делаю программу, которая создает 2 списка, заполняет 1 список рандомными числами, а потом ссылается на второй пустой список и проверяет его на наличие в нем чисел из первого. То есть, заполняет его числами по одному разу, например, имеется список l1 = 4 4 3 3 2 2 4, следовательно, во второй списке должны быть l2 = 4 3 2. Но при выполнении программы, в функции search пишет, что происходит разыменовывание пустого указателя l3. Подскажите пожалуйста, как это исправить
#include <time.h>
using namespace std;
struct list {
int data;
list* next;
};
list* head;
void createlist(int n, list** head) {//создает список
if (n>0)
{
(*head) = new list();
(*head)->data=rand()%10;
(*head)->next = NULL;
createlist(n - 1, &((*head)->next));
}
}
void print(list* head) {//выводит список
cout << "Список имеет значения: ";
while (head != 0) {
cout << head->data << " ";
head = head->next;
}
cout << endl;
}
void search(list*l1, list*l2) {
int i=0, j=0;
while (l1 != NULL) {
j=l1->data;
if (l2==0){
l2->data = j;
l2->next = NULL;
}
else while (l2 != 0 && i!=1) {
if (j==l2->data){
i = 1;
}
else {
l2->data = j;
l2->next = NULL;
i = 1;
}
}
}
}
int main() {
setlocale(0, "RUS");
srand(time(0));
int n;
cout << "Введите количество элементов списка ";
cin >> n;
list* l1;
createlist(n, &l1);// создает первый список
print(l1);// выводит первый список
list* l2 = new list;
search(l1, l2);
print(l2);// выводит результирующий список
}
Ответы (1 шт):
Вместо того, чтобы писать где у вас ошибки, я просто прокомментирую ваш код. В комментарии где стоит ! стоит обратить внимание:
void search(list*l1, list*l2) {
int i=0, j=0;
//Цикл который проходит по первому списку
while (l1 != NULL) {
j=l1->data;
//Если l2 - нулевой указатель
if (l2==0){
//! Записываем l2 поле data и next
//А как мы это делаем? У нас l2 - нулевой указатель
l2->data = j;
l2->next = NULL;
}
//Иначе проходим по второму списку и пока i != 1
else while (l2 != 0 && i!=1) {
//! Если в списке 2 уже есть элемент со значением
//j, то i = 1
//Хорошо вы нашли одинаковый элемент. Просто перейдите
//к следующему элементу в l1
if (j==l2->data){
i = 1;
}
//! Иначе присваиваем l2 data = j и next = NULL и i = 1
// 1*
//И так же устанавливаем i = 1
//То есть после первой итерации у вас i = 1 и цикл остановится
//То есть вы максимум прошли 1 элемент из списка l2
else {
l2->data = j;
l2->next = NULL;
i = 1;
}
}
//Хорошо, а что дальше? l1 равен не NULL, и что вы делаете дальше?
//Может стоит перейти к следующему элементу l1?
}
}
Немного расскажу про 1*:
Если j != l2.data, то вы наверно пытались добавить новый элемент в l2, но все равно сделали не правильно. Никакой новый элемент вы не добавляете, а просто меняете значение последнего на j. Да это и не нужно делать если j != l2.data. Это нужно делать когда вы прошли весь список l2 и не нашли j.
То есть проходите по списку l1, но вам нужно добавить сам переход на следующий элемент. l1 = l1->next
Потом если l2 пустой (l2 == nullptr), то вам нужно проинициализировать список, и для этого нужно передавать указатель l2 по ссылке или указателю.
Иначе вам нужно пройтись по всему списку l2, но нужно поменять условие на l2->next != nullptr т.к. l2 точно не будет nullptr по проверке выше, а указатель на последний элемент нужен будет для добавления нового элемента.
В цикле ищем j среди элементов. Если нашли, то запишите результат поиска в bool isFind иначе переходите к следующему элементу l2 l2 = l2->next
Если isFind == false то вы должны создать для начала новый элемент типа list выделив для него память. Изменить у него значения data на j, next на NULL, а вот последнему элементу l2 вы меняете next на созданный ранее новый элемент.
Удачи!
P.s. да не надо ставить -реп :) я хоть как то помогаю