Lista dwukierunkowa, wypisywanie od końca

0

Nie wiem czy poprawnie inicjalizuję listę dwukierunkową.
Mógłby mi ktoś pomóc i wskazać w jaki sposób wypisać tą listę od końca?

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

struct student {
	int ocena;
	struct student *nast;
	struct student *poprz;
};

int main(){
	struct student *glowa = NULL, *wsk = NULL;
	int i = 0, ile = 3;
	
	while (i < ile){
		if (glowa == NULL){
			glowa = wsk = (struct student*)malloc(sizeof(struct student));
			wsk->poprz = wsk->nast = NULL;
		}
		else{
			wsk->poprz = wsk;
			wsk->nast = (struct student*)malloc(sizeof(struct student));
			wsk = wsk->nast;
		}
		scanf("%d", &wsk->ocena);
		i++;
	}
	i = 0;
	wsk = glowa;
	putchar('\n');
	while (i < ile){
		if (i == 0){
			wsk = wsk->poprz;
		}
		else{
			wsk = wsk->nast;
		}
		printf("%d\n", wsk->ocena);
		i++;
	}
	printf("\nKoniec programu.\n");
	return 0;
}
0

Powinieneś dodać wskaźnik pokazujący na ostatni element listy. W przeciwnym wypadku musisz przelecieć całą listę, żeby znaleźć ostatni element, a później cofać się i wypisywać każdy z elementów.
Nie wiem jak inni, ale ja zawsze jak robię tego typu listę to tworze dwie klasy:

  1. jest konkretnym elementem
  2. jest kontenerem, który zarządza wszystkimi elementami
    przykład:
class element{
    element * prev = NULL;
    element * next = NULL;
}

class container
{
    element * first = NULL;
    element * current = NULL;
    element * last = NULL;
}

Plus oczywiście metody do zarządzania.
Wszystkie jest obsługiwane przez kontener, który wykonuje odpowiednie operacje na liście oraz zwraca tylko to co faktycznie jest potrzebne.

1
void wypisz(struct student *ostatni){
  while(ostatni){
    printf("%d", ostatni->ocena);
    ostatni = ostatni->poprz;
  }
}
 
  • musisz mieć gdzieś zapisany wskaźnik na ostatni element, żeby to wywołać
0

dlaczego nie podzielisz sobie na funkcje i nie ułatwisz tego? http://ideone.com/f4MopI ja zawsze listę opakowuje w dodatkowy typedef i prymitywnie:

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

typedef struct student_t {
	int mark;
	struct student_t *next;
	struct student_t *prev;
} student_t;

typedef struct {
	struct student_t *first;
	struct student_t *last;
} list_t;

list_t *list_init(void) {
	list_t *list = malloc(sizeof(list_t));
	list->first = NULL;
	list->last = NULL;
	return list;
}

void push_back(list_t *list, student_t s) {
	/* tworzymy nowego studenta */
	student_t *new = malloc(sizeof(student_t));
	new->mark = s.mark;
	new->next = NULL;
	new->prev = list->last;

	if(!list->first) /* jezeli lista pusta */
		list->first = new;
	else			/* ostatniemu studentowi mowimy ktory nastepny */
		list->last->next = new;
	list->last = new;
}

void list_free(list_t *list) {
	student_t *ns, *s = list->first;
	while(s) {
		ns = s->next;
		free(s);
		s = ns;
	}
	free(list);
}

int main(void) {
	/* tworzymy sobie nasza liste */
	list_t *lista = list_init();

	/* tworzymy studenta i dodajemy do listy */
	student_t tmp;
	while(scanf("%d",&tmp.mark)==1)
		push_back(lista,tmp);

	student_t *e;
	/* od poczatku */
	for(e = lista->first; e; e = e->next)
		printf("%d ",e->mark);
	printf("\n");

	/* od konca */
	for(e = lista->last; e; e = e->prev)
		printf("%d ",e->mark);
	printf("\n");

	/* sprzatamy po sobie */
	list_free(lista);
	return 0;
}

EDIT: lepsza wersja list_init http://ideone.com/T7W8jd

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