Wątek przeniesiony 2014-10-26 18:19 z C/C++ przez ŁF.

Listy jednokierunkowe - wstawianie nowego elementu przed zadany

0

Witam!
Na uczelni uczymy się właśnie tworzyć i używać list jednokierunkowych. I mieliśmy za zadanie napisać funkcje, które dodają nowy element za i przed wskazany przez q element w liście. Z dodawanie za nie miałem problemu, jednakże z przed już mam.

#include<stdio.h>
#include<stdlib.h>

typedef struct el{
	int dane;
	struct el *nast;
} element;

element *p, *q, *r;
int x, y, z;

element *DNPL(int a, element *l){
	element *q;
	q = malloc(sizeof(element));
	q->dane = a;
	q->nast = l;
	return q;
}

element *DNKL(int a, element *l){
	element *q, *r;
	q = malloc(sizeof(element));
	while (q != NULL){
		printf("%i\n", q->dane);
		q = q->nast;
	}
	if (l == NULL) return q;
	r = l;
	while (r->nast != NULL) r = r->nast;
	r->nast = q;
	return l;
}

void druk_normalny(element *p){
	if (p != NULL){
		printf("%d, ", p->dane);
		druk_normalny(p->nast);
	}
}

void druk_odwrocony(element *p){
	if (p != NULL){
		druk_odwrocony(p->nast);
		printf("%d, ", p->dane);
	}
}

element *znajdz(int x, element *p){
	element *q = p;
	while ((q != NULL) && (q->dane != x)) q = q->nast;
	return q;
}

void dodaj_za(int x, element *q){
	element *r = malloc(sizeof(element));
	r->dane = x;
	r->nast = q->nast;
	q->nast = r;
}

void dodaj_przed(int x, element *q, element *p){
	element *r = NULL;
	if (r->nast == q) DNPL(x, p);
	else{
		while (r->nast != q) r = r->nast;
		element *t = malloc(sizeof(element));
		r->nast = t;
		t->dane = x;
		t->nast = q;
	}
}

int main(){
	p = NULL;
	printf("Podaj elementy list:\n");
	scanf("%i", &x);
	while(x != 0){
		p = DNPL(x, p);
		scanf("%i", &x);
	}

	printf("\nTwoja lista: ");
	q=p;
	druk_normalny(p);

	printf("\nJaki element chcesz znalesc w liscie: "); scanf("%d", &x);
	while (x){
		q = znajdz(x, p);
		if (q != NULL) {
			printf("Znaleziono %i\n", x);
		}
		else{
			printf("Nie ma %i na liscie\n", x);
		}
		scanf("%i", &x);
	}
	
	printf("\nPodaj element, ktory chcesz dodac do listy: ");
	scanf("%d", &x);
	dodaj_przed(x, q, p);

	printf("\nTwoja lista: ");
	druk_normalny(p);

	getchar();
	getchar();
	return 0;
}

Po skompilowaniu wyskakuje błąd "Unhandled exception at 0x00313CF8 in ASD.exe: 0xC0000005: Access violation reading location 0x00000004." przy warunku if w funkcji dodaj_przed.
Byłbym wdzięczny za pomoc.
Pozdrawiam

0

Z dodaj_za też masz problemy, bo wystarczy:

void dodaj_za(int x, element *q) {
    q->nast = DNPL(x,q->nast);
}

Padłeś ofiarą bezsensownego nazywania zmiennych.

void dodaj_przed(int x, element *q, element *p){
    element *r = NULL;
    if (r->nast == q) DNPL(x, p);
    else{
        while (r->nast != q) r = r->nast; // co my tu iterujemy skoro r=NULL w pierwszym wierszu funkcji.
        element *t = malloc(sizeof(element));
        r->nast = t;
        t->dane = x;
        t->nast = q;
    }
}
0

Faktycznie z dodaj_za nie pomyślałem żeby użyć funkcji DNPL.
Co do pętli while, to widzę to tak, że dopóki r->nast nie będzie wskazywała na q mam przechodzić przez kolejne, elementy listy. Nie widzę w sumie innego sposobu by dostać element listy przed q, który swoją drogą jest mi potrzebny.
Zaś co do nazywania zmiennych, to tak zmienne nazywa mój wykładowca i kod który tu wstawiłem jest bezpośrednio z zajęć. Ja tylko dopisałem funkcje dodaj_za i dodaj_przed, z czego jedna nie działa...

0

Jakie r ? r - to zmienna lokalna:

element *r = NULL;
0

Aaa, dobra już wiem. Dzięki.
Zamiast

element *r = NULL; 

powinno być

element *r;
r = NULL; 

Nie kurde, to też nic nie zmienia...:(

1

Czy rozumiesz cokolwiek z tego kodu co przedstawiłeś ?
No chyba że coś dobrego palisz i jesteś obecnie na głębokim haju.

0

Większość, ale nie wszystko.

0

Weź się za naukę, bo jak nie zrobisz tego sam to dalej będzie gorzej.
Nie sądzę aby rozumiałeś większość bo widzę że nie rozumiesz nawet parametrów funkcji którą masz zrobić.

0

Udało mi się częściowo naprawić tą funkcje i rozumiem czemu głupota było ustawianie r na NULL. Jednakże nie rozumiem teraz dlaczego funkcja ma problem z użyciem DNPL w przypadku gdy wskazany element jest na samym początku listy. Więc byłbym wdzięczy za "niestresującą" pomoc.

void dodaj_przed(int x, element *q, element * p){
	element *r = p;
	if (r == q) p = DNPL(x, p);
	else{
		while (r->nast != q) r = r->nast;
		element *t = malloc(sizeof(element));
		r->nast = t;
		t->nast = q;
		t->dane = x;		
	}
}

dodanie znacznika <code class="c"> - @furious programming

0

Ta funkcja nie jest przeznaczona do dodania na początek listy, ponieważ przy dodaniu na początek musisz zmienić początek listy zaś ten początek jest przekazany przez wartość.
Podsumowując, nie zmieniając nagłówka funkcji - nie da się.
Poza tym:

element *dodaj_przed(int x,element *q,element * p){
    element *r=p;
    if (p==q) p=DNPL(x,p);
    else {
        while(r->nast!=q) r=r->nast;
        r->nast=DNPL(x,q);
    }
    return p;
}

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