Listy dwukierunkowe w C

0

Witam, oto program, z operacjami na listach dwukierunkowych. wg. mmie wszystko jest poprawnie, ale program nie odwraca listy
Oto kod:

 
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct element
{
	int k;
	struct element *prev;
	struct element *next;
};
void lista_wyswietl( struct element *head);
struct element* lista_dodaj(struct element *head, struct element *nowy);
struct element* lista_szukaj(struct element *head, int sz);
struct element* lista_usun(struct element *head, struct element *x);
struct element* lista_odwroc(struct element *head);
int main()
{
	struct element *head=NULL, *nowy=NULL, *temp=NULL;
	int liczba;
	char z;
	while(1)
	{
		printf("\nd-dodaj\n");
		printf("w-wyswietl\n");
		printf("s-szukaj\n");
		printf("q=wyjscie\n");
		z=getchar();
		switch(z)
		{
			case 'w': lista_wyswietl(head);
			getch();
			break;
			
			case 'd': nowy=(struct element *)malloc(sizeof(struct element));
			printf("Podaj wartosc do dodania \n");
			scanf("%d", &liczba);
			nowy->k=liczba;
			head = lista_dodaj(head, nowy);
			break;
			case 's': printf("Podaj element do szukania \n");
			scanf("%d", &liczba);
			temp=lista_szukaj(head, liczba);
			if(temp!=NULL)
			printf("Znaleziono element\n");
			else
			printf("Nie znaleziono elementu\n");
			getch();
			case 'u': lista_wyswietl(head);
			printf("Podaj element do usuniecia\n");
			scanf("%d", &liczba);
			temp=lista_szukaj(head, liczba);
			if(temp!=NULL)
			head=lista_usun(head, temp);
			break;
			case 'o': if(head!=NULL)
			{
			head = lista_odwroc(head);
			printf("Lista odwrócona\n");
			lista_wyswietl(head);
			}
			break;
			case 'q': 
			return 0;
			break;
		}
		system("cls");
	}
}
void lista_wyswietl( struct element *head)
{
	struct element *x=head;
	while(x!=NULL)
	{
		printf("%d ", x->k);
		x=x->next;
	}
}
struct element* lista_dodaj(struct element *head, struct element *nowy)
{
	nowy->next=head;
	if(head!=NULL)
	head->prev=nowy;
	head=nowy;
	nowy->prev=NULL;
}
struct element* lista_szukaj(struct element* head, int sz)
{
	struct element *x=head;
	while(x!=NULL &&x->k!=sz)
	x=x->next;
	return x;
}
struct element* lista_usun(struct element* head, struct element* x)
{
	struct element *temp;
	if(x->prev!=NULL)
	x->prev->next=x->next;
	else
	head=x->next;
	if(x->next!=NULL)
	x->next->prev=x->prev;
	return head;
}
struct element* lista_odwroc(struct element* head)
{
	struct element *temp=NULL, *x=NULL, *y=NULL;
	x=head;
	while(x!=NULL)
	y=(struct element*)malloc(sizeof(struct element));
	y->k=x->k;
	temp=lista_dodaj(temp, y);
	x=x->next;
	return temp;
}

Gdzie jest problem?
Są jeszcze jakieś błędy? czy program dobrze napisany?
MAcie jakieś fajne ćwiczenia z C z list dwukierunkowych?
Z góry dziękuję za pomoc.

0

Problem w tym że nie wiesz o tym że instrukcje while/for/if oraz inne obejmują nie tyle instrukcji ile masz w głowie tylko jedną lub tyle ile zaznaczono nawiasami klamrowymi.

Oraz kilka pomniejszych problemów np:

void lista_wyswietl(struct element *head)
  {
   for(;head;head=head->next) printf("%d ", x->k);
  }

Oraz problem z formatowaniem.

0

Mam jeszcze napisać nową listę która przechowuje co drugi znak istniejącej już listy. Zupełnie nie wiem jak to zrobić, może jakieś wskazówki?

0

zacząłem coś pisać

struct element *lista2(struct element *head)
{
	int i=0;
	struct element *x=head;
	while(x!=NULL)
	{	
		if(i%2==0)
		{
		//tu zapisujemy wartosci do rugiej listy.	
		}
		i++;
	}
}

ale nie wiem jak dodać 2listę do jednego programu.
Można ten program też rozwiązać w taki sposób że usuwamy niepotrzebne wartości , co drugi elelment. Ale zadanie mamy rozwiązać na 2 sposoby.

dodane znaczniki <code class="c"> - fp

0

Program pisałem ja, ale miałem zapisane w pseudokodzie algorytmy dodaj, usun, szukaj.
Już napisałem usuwanie co drugiego elementu z listy

struct element *lista2(struct element *head)
{
	int i=1;
	struct element *x=head;
	while(x!=NULL)
	{	
		if(i%2==0)
		{
		lista_usun(head, x);
		}
		i++;
		x=x->next;
	}
	return head;
}

Teraz jak napisać program/funkcje co przepisuje z 1 listu do drugiej co drugi element?

dodane znaczniki <code class="c"> - fp

0

Nie zauważyłem, że wcześniej napisałeś. Jako użytkownik anonimowy chyba nie mogę edytować.
Dzięki już chyba rozumiem idee list.

Mam chyba jeszcze jeden problem.
Funkcja usuwa ostatni element z listy

struct element* lista_usunk(struct element *head)
{
	struct element *x=head;
	while(x!=NULL)
	{
		x=x->next;
	}
	lista_usun(head, x);
	return head;
} 

tak ją wywołuję

 
           case 't': if(head!=NULL)
	{
	head=lista_usunk(head);
	printf("Usunieto ostatni element!\n");
	lista_wyswietl(head);
	}
	getch();
	break;

po uruchomieniu programu i dodaniu elementów do listy i wcisnięciu t program sie zawiesz co może być?

0

po uruchomieniu programu i dodaniu elementów do listy i wcisnięciu t program sie zawiesz co może być?

A spytaj autora programu po kiego lista_usun zwraca wskaźnik?

0

Można trochę jaśniej.

0

Mam chyba jeszcze jeden problem.
Funkcja usuwa ostatni element z listy
struct element* lista_usunk(struct element *head)
{
struct element *x=head;
while(x!=NULL)
{
x=x->next;
}
lista_usun(head, x);
return head;
}

tak ją wywołuję

       case 't': if(head!=NULL)
    {
    head=lista_usunk(head);
    printf("Usunieto ostatni element!\n");
    lista_wyswietl(head);
    }
    getch();
    break;

po uruchomieniu programu i dodaniu elementów do listy i wcisnięciu t program sie zawiesz co może być?

Sprawdź, co Ci zwraca funkcja

 struct element* lista_usunk(struct element *head)

Według Mnie zawsze zwróci NULL.

 
struct element *x=head;
        while(x!=NULL)

Zastanówmy się. wskaźnik x wskazuje na pierwszy element listy. Wiemy, że ostatni element listy obiera nast. element jako NULL. Tak więc musimy wyjść z pętli nie wtedy (jak wynika z twojego warunku), kiedy x == NULL tylko wtedy, gdy x -> nast == NULL.

0

Co prawda to prawda, ale mam jednak problem ze stworzeniem nowej listy i przepisaniem do niej co drugiego znaku.
Zrobiłem to tak

struct element* lista_2(struct element *head)
{
	struct element *temp=NULL, *x=NULL, *y=NULL;
	x=head;
	int i=0;
	while(x!=NULL)
	{
		if(i%2==0)
		{
			y=(struct element*)malloc(sizeof(struct element));
			y->k=x->k;
			temp=lista_dodaj(temp, y);
		}
		x=x->next;
		i++;
	}
	return temp;
}
 

ale lista przepisuje co drugi znak ale od tyłu np.
dla listy 1 2 3 4
przepisze 3 i 1
a załozeniem zadania jest aby wipisała 1 i 3.
Ile bym nie myślał to nie wiem jak to zrobić aby było ok.
tzn wiem że jest źle napisane.

0

Nikt nie pomoże??

0

Moim zdaniem, za każdym razem dodajesz element na początek listy. Znów opiszę to na przykładzie:
LISTA1: 1,22,34,44,75,96
LISTA2:

cykl1: 1%2 jest ! 0.
cykl2: 2%2 jest = 0.
LISTA2: 22
cykl3: 3%2 jest ! 0.
cykl4: 4%2 jest = 0.
LISTA2: (dodajemy na poczatek listy) 44, 22
i tak dalej...

Dam Ci przykład funkcji jaką zrób, przy okazji poćwiczysz listy dwukierunkowe.

 bool dodaj_element(int pozycja, struct element *pierwszy, struct element *nowy);

Niech pozycja liczy się od "1" (oznacza to, że nowy element znajdzie się na początku listy). Jeżeli pozycja będzie mniejsza od zera lub większa od dotychczasowej ilości elementów, wówczas nowy element ma być umieszczony na końcu listy.

Podpowiedź:
LISTA: a, b, c, d, e
pozycja = 3
nowy = S

nowy umieśc miedzy 2 a 3 elementem (element 3 stanie się czwartym).
Jak to napiszesz nie będziesz miał problemów z listami i rozwiąże się twój problem.

====================

Edit.

Ebać.
Przeczytaj funkcje jakie "sam" napisałeś. jest w niej pewna o nazwie "odwróć". Jak odwrócisz elementy otrzymasz pożądany wynik. =.=

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