Vícenasobný spojový seznam – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Vícenasobný spojový seznam – C / C++ – Fórum – Programujte.comVícenasobný spojový seznam – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
Redby0
Návštěvník
16. 11. 2011   #1
-
0
-

Řeším takovou věc. Mám udělaný lineární spojový seznam v C. Funguje to všechno perfektně. Problém ale nastal když jsem chtěl udělat druhej seznam. Např. Mám seznamA kde jsou prvky alfa, beta, gama potom chci mít seznamB kde budou prvky uno, duo, tre..

Strukturu mám definovanou takto:

struct node {
	struct node *next;
	char *word;
};

Seznamy si vytvořím takto:

 	struct node *seznamA;
	struct seznamA *head;
	seznamA = malloc(sizeof(seznamA));

A stejným způsobem i pro seznamB.

Otázka zní jak modifikovat tuto funkci aby fungovala že při předáním parametru seznamA uložila prvek do seznamuA a při parametru seznamB uložila do seznamuB

void add(char *wordToAdd) {
	saveWord *item;
	item = malloc(sizeof(saveWord));
	item->word = malloc(sizeof(wordToAdd));
	strcpy(item->word, wordToAdd);
	item->next = head;
	head = item;
}

Je mi jasný že tam nedude saveWord, ale pořád se v tom nějak motám..

Nahlásit jako SPAM
IP: 88.103.128.–
Reklama
Reklama
Redby0
Návštěvník
16. 11. 2011   #2
-
0
-

Tak jsem při googlu našel tento způsob, kterej je dle mého nejblíže řešení ale nefunguje jak má.. Vypis je Nazdar a NULL namísto očekáváného NazdarAhoj

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


struct list {
	struct list *next;
	char *word;
};

void add(char *wordToAdd, struct list *);

int main() {

	struct list *seznamA, *seznamB;
	seznamA = malloc(sizeof(struct list));
	add("Ahoj", seznamA);
	add("Nazdar", seznamA);

	printf("%s", seznamA->word);
	printf("%s", seznamA->next->word);

	return 0;
}

void add(char *wordToAdd, struct list *temp) {


	temp->word = malloc(sizeof(wordToAdd));
	strcpy(temp->word, wordToAdd);
	temp->next = malloc(sizeof(struct list));
	temp = temp->next;
	temp->next = NULL;

}


Nahlásit jako SPAM
IP: 88.103.128.–
KIIV+42
God of flame
16. 11. 2011   #3
-
0
-

obdivuju ten kousek kodu ... vypada skoro jako ze dava smysl ale kdyz se nad tim clovek zamysli tak je to ukazkovy priklad jak se to nema delat

void add(char *wordToAdd, struct list *temp) {

        // nasledujici dva radky prepisi slovo ktere uz tam bylo, zaroven se elegantne zbavi pointeru na pamet kde je ulozene - memory leak
	temp->word = malloc(sizeof(wordToAdd));
	strcpy(temp->word, wordToAdd);

        // tady se dejme tomu vytvori dalsi prvek - no jo ale co kdyz uz dalsi prvek existuje? opet se zbavime pointeru na nej a data v klidu odpocivaji v pameti
	temp->next = malloc(sizeof(struct list));

        // toto uz by mohlo i teoreticky davat minimalni smysl:
	temp = temp->next;
	temp->next = NULL;

}

takze pokud chces delat zasobnik (coz predpokladam podle tveho ocekavaneho zapisu)
 tak to bude chit predat   list ** pocatek; vytvorit si  list temp jako lokalni promennou...

a temp->next  dat  *pocatek  ...  a pak na zaver prepsat *pocatek = temp;

EDIT: a jeste jedna docela fatalni chyba:   sizeof(wordToAdd)  vraci na 32b systemu 4!!!!!  tj. nejen memory leak ale jeste k tomu buffer overflow pokud bude slovo delsi jak 3 znaky + 1 ukoncujici ->  delka retezce se da zjistit napriklad pomoci strlen

Nahlásit jako SPAM
IP: 94.112.32.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Redby0
Návštěvník
17. 11. 2011   #4
-
0
-

Super, díky, vypadá to že to takto funguje až na jednu maličkost. Neukladá to na první prvek seznamu, což musím ještě pořešit. Můj kod vypadá nyní takto:

void add(char *wordToAdd, struct list **begin) {
    struct list *temp;
    temp = malloc(sizeof(struct list));
    temp->next = *begin;
    temp->word = malloc(sizeof(wordToAdd));
    strcpy(temp->word, wordToAdd);
    *begin = temp;
}

Pokud vložím dva prvky prvky tak jeden je na seznam->next-word a druhej na seznam->next-next-word a na seznam->word je NULL

Nahlásit jako SPAM
IP: 85.161.223.–
KIIV+42
God of flame
17. 11. 2011   #5
-
+1
-
Zajímavé

krom toho ze si tam nechal to svinstvo: malloc(sizeof(wordToAdd));  tak se to zda byt funkcni...

(hde hlavne o delsi retezce co bys tam mohl chtit dat... )

Neco takoveho sem zkousel ja:

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

struct list {
  struct list * next;
  char * word;
};

void add(char *, struct list **);
void print(struct list *);
void destroy(struct list **);

int main() {
  struct list * A = NULL, *B = NULL;

  add("prvek 1A                       ", &A);
  add("prvek 2A                       ", &A);
  add("prvek 1B                       ", &B);
  add("prvek 2B                       ", &B);
  add("prvek 3A                       ", &A);

  print(A);
  print(B);

  destroy(&A);
  destroy(&B);
  return 0;
}

void add(char *wordToAdd, struct list **begin) {
    struct list *temp;
    temp = malloc(sizeof(struct list));
    temp->next = *begin;
    printf("sizeof: %d strlen: %d\n", sizeof(wordToAdd), strlen(wordToAdd));
    temp->word = malloc(strlen(wordToAdd)+1);
    strcpy(temp->word, wordToAdd);
    *begin = temp;
}

void print(struct list * ptr) {
  while ( ptr != NULL ) {
    printf("'%s'",ptr->word);
    ptr = ptr->next;
  }
  printf("\n");
}

void destroy(struct list **begin) {
  struct list * ptr = *begin;
  while ( ptr != NULL ) {
    *begin = ptr->next;
    free(ptr->word);
    free(ptr);
    ptr = *begin;
  }  
}

dulezity je pak vypis  sizeof a strlen z wordToAdd... vsimni si drobneho rozdilu

Nahlásit jako SPAM
IP: 94.112.32.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Redby0
Návštěvník
17. 11. 2011   #6
-
0
-

#5 KIIV
Super funguje to. Problemek byl ve volání funkce. Prostě ty ukazatle mi dávají zabrat..:-( Taky díky za tip na sizeof. Ted pro změnu řeším odebrání prvku které opět nefunguje. Udělal jsem to stylem dle tebe, ale funguje mi odebrání jen prvního prvku. Bude asi problem s tim prev ale nějak na to nemohu přijít...

void pull(char *wordToRemove, struct list **begin) {
	struct list *temp = NULL, *prev = NULL;
	for (temp = *begin, prev = NULL; temp != NULL; prev = temp, temp = temp->next) {
		if (strcmp(temp->word, wordToRemove) == 0) {
			if (prev == NULL) {
				temp = temp->next;
			} else if (temp->next == NULL) {
				prev->next = NULL;
			} else {
				prev->next = temp->next;
			}
		}
	}

	free(prev->word);
	free(prev);
}

Když jsem to používal v modulu jen pro jeden seznam tak to bylo OK.. Tady to opět zlobí... Snad někdy ty pointery zvladnu..

Nahlásit jako SPAM
IP: 78.136.160.–
KIIV+42
God of flame
17. 11. 2011   #7
-
0
-

mel bys znat prev jen proto, abys mohl "preklenout" ten mazanej prvek... potrebujes najit prvek, ktery chces smazat, musis znat jeho predchudce a nasledovnika mas v  ->next ... takze zkopirujes si prvek do treba "toFree", prepises ->next predchudce pomoci ->next mazaneho prvku, a pak uz ten prvek muzes pomoci toFree uvolnit

(nejlepsi je si to asi nakreslit na papire ... pekny sipky jako "pointery" a tak... pak je lip videt co mas delat)

Nahlásit jako SPAM
IP: 94.112.32.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Redby0
Návštěvník
18. 11. 2011   #8
-
0
-

#7 KIIV
Upps, školácká chyba. Nastavoval jsem si ukazatele na prev a pak jsem na prev uvolnil pamět :-( Mnohokráte děkuji za pomoc.. Již to běhá dle mých představ...

Nahlásit jako SPAM
IP: 88.103.128.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 120 hostů

Podobná vlákna

Spojový seznam — založil TarderOrtex

Spojový seznam — založil Luckin

Spojový seznam — založil Jakub

Spojový seznam — založil lubabe

Linearní spojový seznam — založil Rivers

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý