lista zadanie

0

Mam taki problem,chcę stworzyć listę jednokierunkową jak w tresci zadania i mam problem czy w funkcji arrayToList dobrze próbuję ją zaimplementować. Chodzi mi o stworzenie listy na bazie danych z tablicy i podstawienie z niej danych. Czy w funkcji arrayTo List trzeba użyć head który pojawia się potem oraz czy trzeba tworzyć jakiś konstruktor do tego? Kod nie jest jeszcze dobry, ale czy w taki sposób się to robi?
Tutaj jest kod z poleceniami:

#include <iostream>

using namespace::std;

struct Node {
	int data;
	Node* next;
};

Node* arrayToList(const int arr[], size_t size) {
	Node *number = new Node;
	number = 0;
	Node *nextnumber = new Node;
	nextnumber = 0;
	for (size_t i = 0; i < size; ++i)
	{
		number->data = arr[i];
		number = nextnumber;
	}
	return number;
}

arrayToList pobiera tablicę int’ów i jej wymiar. Zadaniem funkcji jest utworzenie listy jednokierunkowej obiektów struktury Node,
zawierającej w kolejnych węzłach kolejne liczby z przekazanej tablicy (w takiej samej kolejności!). Funkcja zwraca wskaźnik do „głowy” utworzonej listy.

Node* removeOdd(Node * head) { 

}

removeOdd pobiera wskaźnik do „głowy” listy i zwraca wskaźnik do „głowy” listy powstającej z listy pierwotnej po usunięciu wszystkich węzłów,
w których data jest liczbą nieparzystą. UWAGA: Funkcja ta nie powinna tworzyć żadnych nowych węzłów, tylko usuwać te zawierające nieparzyste dane.
Jeśli lista zawiera same liczby nieparzyste, wszystkie węzły powinny zostać usunięte, a funkcja powinna zwrócić nullptr.
Zapewnić, by przy każdym usuwaniu węzła funkcja drukowała wartość danej w nim zawartej, abyśmy widzieli, że rzeczywiście węzły te są usuwane.

void showList(const Node * head) { 

}

showList drukuje zawartość listy (dane z kolejnych węzłów, w jednej linii, oddzielone znakami odstępu).

void deleteList(Node * &head) { 

}

deleteList usuwa wszystkie węzły listy; wskaźnik do „głowy” przesłany jest przez referencję, aby funkcja mogła zmienić jego oryginał (na nullptr,
co odpowiada liście pustej). Funkcja wypisuje informacje o usuwanych węzłach.

int main() { 
	int arr[] = { 1,2,3,4,5,6 };
	size_t size = sizeof(arr) / sizeof(*arr);
	Node* head = arrayToList(arr, size);
	showList(head);
	head = removeOdd(head);
	showList(head);
	deleteList(head);
	showList(head);
}

/*
1 2 3 4 5 6
DEL:1 DEL:3 DEL:5
2 4 6
del:2 del:4 del:6
Empty list

to jest co powinno wyświetlić
*/
1

Najlepiej zrobić funkcję push (dodajaca element na poczatek linked listy) i zapuścić ją w pętli:

struct Node {
	int data;
	Node * next;
};
void push(Node** headPtr, int e) {
	Node *newNode = new Node;
	newNode->data = e;
	newNode->next = *headPtr;
	*headPtr = newNode;
}

Node* arrayToList(const int arr[], size_t size) {
    Node *list = new Node;
    list->data = arr[0];
    if (size <= 1) return list;
    for (size_t i = 1; i < size; ++i){
        push(&list, arr[i]);
    }
    return list;


int main(){
	int a[3] = {1, 2 ,3};
	Node * l = arrayToList(a, 3);
	return 0;
}

EDYCJA: Zmieniłem funkcję arrayToList, tworzyła listę z dodatkowym zerem na początku.

0

Czy mógłby ktoś spojrzeć i powiedzieć jak poprawić te funkcje by działały nie wiem jak pozbyć się błędów.


#include <iostream>
#include "Świderski8.h"

using namespace::std;

struct Node {
	int data;
	Node* next;
};

Node* arrayToList(const int arr[], size_t size);

Node* removeOdd(Node* head); 

void showList(const Node* head);

void deleteList(Node*& head);

int main() { 
	int arr[] = { 1,2,3,4,5,6 };
	size_t size = sizeof(arr) / sizeof(*arr);
	Node* head = arrayToList(arr, size);
	showList(head);
	head = removeOdd(head);
	showList(head);
	deleteList(head);
	showList(head);
}

Node* arrayToList(const int arr[], size_t size) {
	Node* number = new Node;
	Node* head = new Node;
	for (size_t i = 0; i < size; ++i)
	{
		number->data = arr[i];
		number->next = head;
		head = number;
	}
	return number;
}

Node* removeOdd(Node* head) {
	Node* number;
	number = head;
	bool allnumber = true;
	while (number->next = !nullptr)
	{
		if (number->data % 2 = 1 && allnumber == true) {
			head = number->next;
			delete number;
			cout << number->data;
		}
		else(allnumber = false);
		return nullptr;
	}
}

void showList(const Node * head) {
	for (; head; head = head->next)
	{
		cout << head->data << " ";
	}
}

void deleteList(Node*& head) {
	Node* number;
	number = head;
	while (number->next =! nullptr)
	{
		head = number->next;
		delete number;
	}
}

0

Napisałem jak akurat odpowiedziałeś, a możesz zobaczyć czy to co ja zrobiłem jest w miarę dobrze?

0

W ten sposób arrayToList nie może działać - nie Rezerwujesz pamięci na kolejne węzły(Zobacz na mój post). Co do usuwania, to trzeba śledzić dwa wskazniki, tak jak tutaj:
https://www.cs.bu.edu/teaching/c/linked-list/delete/
Usuwanie listy:
https://www.geeksforgeeks.org/write-a-function-to-delete-a-linked-list/
Drukowanie jest trywialne.

0

Mógłbyś przy okazji wyjaśnić dlaczego w funkcji push użyłeś 2 wskażników (**), nie za bardzo rozumiem jak to działa.

0

Wysłałem wskaźnik do referencji na głowę, tak mi łatwiej manipulować listą i widać w funkcji, że wysyłany jest adres (&list).

0

Mam jeszcze pytanie odnośnie tych funkcji. Starałem się zrobić to na bazie linku który podesłałeś odnośnie usuwania elementów z listy ale nie wiem czy mam to dobrze, zastanawiam się czy nullptr jest wymagany by go zwracać czy to się dzieje automatycznie. I jeszcze w sprawie wyświetlania, możliwe że coś żle robię ale jako że wyświetlają mi się dane od tyłu zastanawiam się jak to poprawić. Chciałem użyć kodu do wyświetlania odwróconych elementów listy, ale mam błąd że wychodzę poza zakres. Mógłbyś napisać mi jak to poprawić?

void del(Node** headRef) 
{
	Node* current = *headRef;
	Node* next;

	while (current != NULL)
	{
		next = current->next;
		free(current);
		current = next;
	}
	*headRef = NULL;
}

Node* removeOdd(Node* head) {
	while (head != NULL)
	{
		if (head->data%2 == 1)
		{
			cout << "Del:" << head << " ";
			del(&head);
		}
               if (head)
                  head = head->next;
	}
	return head;
}

void showList(const Node* head) {
/*	if (head == nullptr) return;
	if (head->next != nullptr)
		showList(head->next);
	cout << head->data << " ";
*/for (; head; head = head->next)
	{	
	cout << head->data << " ";
	if (head->next == nullptr) return;
	}
}

void deleteList(Node*& head) {
	Node* current = head;
	Node* next;

	while (current != NULL)
	{
		cout << "del: " << current << " ";
		next = current->next;
		free(current);
		current = next;
	}
	head = NULL;
}

0

Drukowanie, teraz można debugować:)

void printList(Node * head) {
	std::cout << "[";
	Node * tmp = head;
	while (nullptr != tmp) {
		std::cout << tmp->data <<",";
		tmp = tmp->next;
	}
	std::cout <<"]\n";
}
0

czy jesteś pewny że ta funkcja działa, jak się debuguje mam wynik 6,5,4,3,2,1,-842150451, a potem zgłasza wyjątek naruszenia dostępu do odczytu i dalej nie idzie. czy to nie trzeba postawić warunku w którym jeżeli następny element jest równy NULL to wyjdzie z listy, ja próbuję ale to nic nie daje

0

Jestem pewien, że działa, jaką listę drukujesz?

0

W mainie jest showList(head), czy to nie o to chodzi?

0

Wrzuciłem powyżej poprawną funkcję drukującą.

0

w takim razie co jest jeszcze żle w tym zadaniu że wyrzuca taki błąd? Maina nie mogę zmieniać więc jak mam to poprawić?

0

Użyłem dokładnie tego co napisałeś, ale to i tak nie usunęło tego błędu.

0
#include <iostream>

using namespace ::std;

struct Node
{
    int data;
    Node* next;
};

void push(Node** headPtr, int e)
{
    Node *newNode = new Node;
    newNode->data = e;
    newNode->next = *headPtr;
    *headPtr = newNode;
}

Node *arrayToList(const int arr[], size_t size)
{
    Node* list = new Node;
    for (size_t i = 0; i < size; ++i)
    {
        push(&list, arr[i]);
    }
    return list;
}

void del(Node **headRef)
{
    Node *current = *headRef;
    Node *next;

    while (current != nullptr)
    {
        next = current->next;
        free(current);
        current = next;
    }
    *headRef = nullptr;
}

Node *removeOdd(Node *head)
{
    while (head != nullptr)
    {
        if (head->data % 2 == 1)
        {
            cout << "Del:" << head << " ";
            del(&head);
        }
        if (head)
            head = head->next;
    }
    return head;
}

void showList(Node* head) {
    std::cout << "[";
    Node* tmp = head;
    while (nullptr != tmp) {
        std::cout << tmp->data << ",";
        tmp = tmp->next;
    }
    std::cout << "]\n";
}

void deleteList(Node *&head)
{
    Node *current = head;
    Node *next;

    while (current != nullptr)
    {
        cout << "del: " << current << " ";
        next = current->next;
        free(current);
        current = next;
    }
    head = nullptr;
}

int main()
{
    int arr[] = { 1, 2, 3, 4, 5, 6 };
    size_t size = sizeof(arr) / sizeof(*arr);
    Node* head = arrayToList(arr, size);
    showList(head);
    head = removeOdd(head);
    showList(head);
    deleteList(head);
    showList(head);
}

0

removeOdd to delikatne przerobienie usuwania pojedynczego elementu, zmieniony warunek i usunięty return - żeby przeszła po całej liście.

void removeOdd(Node **listP){
     Node *currP, *prevP;
	prevP = NULL;
	for (currP = *listP;
		currP != NULL;
		prevP = currP, currP = currP->next) {

    if (currP->data % 2 == 1) {
      if (prevP == NULL) {
        *listP = currP->next;
      } else {
        prevP->next = currP->next;
      }
      delete(currP);
    }
  }
}
0

Czy po tym działa ci zadanie tak jak powinno? U mnie pojawiły się nowe błędy.

0

Jest OK, taki main:

int arr[] = { 1, 2, 3, 4, 5, 6 };
    size_t size = sizeof(arr) / sizeof(*arr);
    Node* head = arrayToList(arr, size);
	printList(head);
	removeOdd(&head);
	printList(head);
0

Czy u ciebie to zadanie działa tak jak powinno?

0

Mógłbyś wrzucić swój kod z tego, chciałbym go porównać ze swoim, może u siebie coś żle napisałem że mi nie działa?

1

arrayToList jest zmieniona, edytowałem post.

void printList(Node * head);
struct Node {
	int data;
	Node * next;
};
void push(Node** headPtr, int e) {
	Node *newNode = new Node;
	newNode->data = e;
	newNode->next = *headPtr;
	*headPtr = newNode;
}

Node* arrayToList(const int arr[], size_t size) {
    Node *list = new Node;
    list->data = arr[0];
    if (size <= 1) return list;
    for (size_t i = 1; i < size; ++i){
        push(&list, arr[i]);
    }
    return list;
}


void removeOdd(Node **listP){
     Node *currP, *prevP;
	prevP = NULL;
	for (currP = *listP;
		currP != NULL;
		prevP = currP, currP = currP->next) {

    if (currP->data % 2 == 1) {
      if (prevP == NULL) {
        *listP = currP->next;
      } else {
        prevP->next = currP->next;
      }
      delete(currP);
    }
  }
}

int main(){
	int arr[] = { 1, 2, 3, 4, 5, 6 };
    size_t size = sizeof(arr) / sizeof(*arr);
    Node* head = arrayToList(arr, size);
	printList(head);
	removeOdd(&head);
	printList(head);
	return 0;
}
void printList(Node * head) {
	std::cout << "[";
	Node * tmp = head;
	while (nullptr != tmp) {
		std::cout << tmp->data <<", ";
		tmp = tmp->next;
	}
	std::cout <<"]\n";
}
0

Dodałem na początku tylko include<iostream> i namespace std , ale pomimo uruchomienia zadania wyrzuca mi 6 błędów, tak poza tym czy przypadkiem nie usunąłes funkcji deletelist czy ona była po prostu dobrze?

0

Mam tylko te trzy funkcje skopiowane: arrayToList, push i removeOdd, innych nie sprawdzałem. Jakie błędy?

0

Chyba najłatwiej ci będzie zobaczyć czy cały ten mój kod działa, ale głównie chodzi o definicje funkcji lokalnych które są niedozwolone, tak mi pisze.

0

W komentarzach jest to czego nie ma u ciebie

#include <iostream>

using namespace ::std;

void printList(Node* head);

struct Node {
	int data;
	Node* next;
};
void push(Node** headPtr, int e) {
	Node* newNode = new Node;
	newNode->data = e;
	newNode->next = *headPtr;
	*headPtr = newNode;
}

Node* arrayToList(const int arr[], size_t size) {
	Node* list = new Node;
	list->data = arr[0];
	if (size <= 1) return list;
	for (size_t i = 1; i < size; ++i) {
		push(&list, arr[i]);
	}
	return list;
}

/*
void del(Node **headRef)
{
    Node *current = *headRef;
    Node *next;

    while (current != nullptr)
    {
        next = current->next;
        free(current);
        current = next;
    }
    *headRef = nullptr;
}
*/

void removeOdd(Node** listP) {
	Node* currP, * prevP;
	prevP = NULL;
	for (currP = *listP;
		currP != NULL;
		prevP = currP, currP = currP->next) {

		if (currP->data % 2 == 1) {
			if (prevP == NULL) {
				*listP = currP->next;
			}
			else {
				prevP->next = currP->next;
			}
			delete(currP);
		}
	}
} 

/*
void deleteList(Node *&head)
{
    Node *current = head;
    Node *next;

    while (current != nullptr)
    {
        cout << "del: " << current << " ";
        next = current->next;
        free(current);
        current = next;
    }
    head = nullptr;
}*/

int main() {
	int arr[] = { 1, 2, 3, 4, 5, 6 };
	size_t size = sizeof(arr) / sizeof(*arr);
	Node* head = arrayToList(arr, size);
	printList(head);
	removeOdd(&head);
	printList(head);
	return 0;
}

void printList(Node* head) {
	std::cout << "[";
	Node* tmp = head;
	while (nullptr != tmp) {
		std::cout << tmp->data << ", ";
		tmp = tmp->next;
	}
	std::cout << "]\n";
}

0

Ale to trochę dziwne, bo nawet jak wziąłem twój kod to i tak mam błędy kompilacji i nie mogę go uruchomić.

0

Deklaracja printList musi być niżej, dałem nad main.

0

Tak wiem, pokażę ci kod do tego zadania który właśnie ktoś jeszcze pomógł mi zrobić daj znać czy ci działa bo u mnie jest problem

#include <iostream>

using namespace ::std;

struct Node
{
    int data;
    Node* next;
};

void push(Node** nodePtr, int e)
{
    Node* newNode = new Node;
    newNode->data = e;
    (*nodePtr)->next = newNode;
    *nodePtr = newNode;
}

Node* arrayToList(const int arr[], size_t size)
{
    Node* list = new Node;
    list->data = arr[0];
    Node* tmp = list;
    if (size <= 1) return list;
    for (size_t i = 1; i < size; ++i)
    {
        push(&tmp, arr[i]);
    }
    return list;
}

void removeOdd(Node** listP)
{
    Node* currP, * prevP;
    prevP = nullptr;
    currP = *listP;
    while (
        currP != nullptr)
    {

        if (currP->data % 2 == 1)
        {
            if (prevP == nullptr)
            {
                *listP = currP->next;
            }
            else
            {
                prevP->next = currP->next;
            }
            Node* tmp = currP;
            currP = currP->next;
            cout << "DEL:" << tmp->data << " ";
            delete tmp;
        }
        else {
            prevP = currP;
            currP = currP->next;
        }
    }
    cout << endl;
}

void printList(Node* head)
{
    std::cout << "[";
    Node* tmp = head;
    if (tmp != nullptr)
    {
        cout << tmp->data;
        tmp = tmp->next;
        while (nullptr != tmp)
        {
            std::cout << "," << tmp->data;
            tmp = tmp->next;
        }
    }
    std::cout << "]\n";
}

void deleteList(Node** head)
{
    Node* current = *head;

    while (current != nullptr)
    {
        Node* tmp = current;
        cout << "del: " << tmp->data << " ";
        current = current->next;
        delete tmp;
    }
    cout << endl;
    *head = nullptr;
}

int main()
{
    int arr[] = { 1, 2, 3, 4, 5, 6 };
    size_t size = sizeof(arr) / sizeof(*arr);
    Node* head = arrayToList(arr, size);
    printList(head);
    removeOdd(&head);
    printList(head);
    deleteList(&head);
    printList(head);
}

0

Dobra już się wyjaśniło. visual studio działa inaczej niż Clion i sam nie inicjalizuje zmiennych tu był mój błąd, ale kiedy poprawiłem już działa, w kazdym razie wielkie dzięki za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1