Trädtraversering. Binärt träd. Trädtraversering djupet-först. Trädtraversering bredden-först

Relevanta dokument
Operatoröverlagring. endast operatorsymboler definierade i C++ kan överlagras = += -= *= /= %= ^= &= = <<= >>= < > <= >= ==!= && > ->*, [ ] ( )

TDIU01 Programmering i C++

TDDC76 - Programmering och Datastrukturer

Skapa, kopiera och destruera klassobjekt

Lektionsuppgifter. TDDI14 Objektorienterad programmering. Lektionsplanering Lektion Lektion Lektion

TDDC76 - Programmering och Datastrukturer

Tommy Färnqvist, IDA, Linköpings universitet

Linjärt minne. Sammanhängande minne är ej flexibelt. Effektivt

Programsystem konstruktion med C++ (2D1387) Innehåll. övning 2 klasser och arv

Kapitel 6 - Undantag

TDIU20 - Objektorienterad programmering i c++ - föreläsning 6

Innehåll. Konstruktorer vid arv Regler för basklassens konstruktor. Konstruktorer vid arv. Konstruktorer vid arv. Konstruktorer vid arv

Programmering i C++ EDA623 Arv. EDA623 (Föreläsning 6) HT / 42

Föreläsning 9 Innehåll

DD2387 Programsystemkonstruktion med C++ Tentamen 1 Torsdag 7 januari 2016, 14:00-18:00

Innehåll. 1 Kort om dynamisk polymorfism. 2 Arv i C++ 3 Multipelt arv. 4 Något om statisk polymorfism. class Container {

Innehåll. Typomvandlingar (casting) Implicita Typomvandlingar. Typomvandlingar (casting) Implicita Typomvandlingar

TDDC76 - Programmering och Datastrukturer

TDDI14 Objektorienterad programmering

Laboration 3. Kalkylator för aritmetiska uttryck. Kalkylatorn ska kunna läsa antingen enbokstavskommandon eller infixuttryck. Exempel på infixuttryck:

TDIU20 - Objektorienterad programmering i c++ - föreläsning 4

Innehåll. Pekaren this Självreferens. Klasser Resurshantering, representation. Överlagring av operatorer. Överlagring av operatorer

Objektorientering - Arv och polymorfi. Eric Elfving Institutionen för datavetenskap

TDDC76 PoD OH Föreläsning C Klasser

Klassmedlemmar. Klasser. Konstruktion av en enskild, icke-trivial klass. Klassen String funktionalitet

TDIU01 - Programmering i C++, grundkurs

Tentamen, Algoritmer och datastrukturer

Programmering i C++ EDA623 Objektorienterad programutveckling. EDA623 (Föreläsning 5) HT / 33

TDDC76 Programmering och datastrukturer

Innehåll. Pekare Exempel

Innehåll. Pekare Exempel

Datastrukturer i kursen. Föreläsning 8 Innehåll. Träd rekursiv definition. Träd

Kalkylator för aritmetiska uttryck

Klasser. Kapitel 2. Kapitel 2 - Klasser, medlemmar och arv. Klasser. Klasser Medlemmar Arv

Föreläsning Datastrukturer (DAT036)

Inlämningsuppgiften. Föreläsning 9 Innehåll. Träd. Datastrukturer i kursen

Introduktion till arv

Klasser. Konstruktion av en enskild, icke-trivial klass

Klasser. Klassen String funktionalitet. Klassen String funktionalitet, forts. Klassen String funktionalitet, forts. Vad ska man kunna göra?

Innehåll. Parametriserade typer. Klassmallar. Klassmallen Vektor Konstructor med std::initializer_list. Klassmallen Vektor Medlemsfunktioner

Objektorientering - Arv och polymorfi

Föreläsning 13. Träd

Abstrakta datatyper. Primitiva vektorer. Deklarera en vektor

Programmering i C++ EDAF30 Dynamiska datastrukturer. EDAF30 (Föreläsning 11) HT / 34

TENTAMEN: Algoritmer och datastrukturer. Läs detta! Uppgifterna är inte avsiktligt ordnade efter svårighetsgrad.

Föreläsning 9 Innehåll

Del2 Klasser, medlemmar och arv Ämnesområden denna föreläsning:

Programmering i C++ EDA623 Dynamiska datastrukturer. EDA623 (Föreläsning 11) HT / 31

Kalkylator för aritmetiska uttryck

Tillämpad programmering

TDDC76 PoD OH Föreläsning C Härledda klasser

Introduktion. Klasser. TDP004 Objektorienterad Programmering Fö 2 Objektorientering grunder

Programsystemkonstruktion med C++

Föreläsning 7. Träd och binära sökträd

*:85/ID200V C++ HT07. Föreläsning 8 Medlemspekare Undantagshantering Namnrymder

Dynamisk bindning och polymorfism

Innehåll. Resource handles. Resurshantering. Minnesallokering. Minnesallokering Exempel: allokering på stacken. 7. Resurshantering, Felhantering

Innehåll. Exceptionella händelser (exceptions, undantag ) Felhantering Tre nivåer av felhantering: Nivå 2: exceptions (eller returvärde)

Algoritmer och datastrukturer 2012, föreläsning 6

public boolean containskey(string key) { return search(key, head)!= null; }

Tentamen Programmeringsteknik II Inledning. Anmälningskod:

Programmering i C++ EDA623 Mer om klasser. EDA623 (Föreläsning 6) HT / 26

Innehåll. Användardefinierade typer. Användardefinierade typer Kategorier. Konstruktorer. Konstruktorer Två sätt att skriva initiering av medlemmar

Föreläsning 7. Träd och binära sökträd

C++ Objektorientering - Klasser. Eric Elfving

Inom datalogin brukar man använda träd för att beskriva vissa typer av problem. Om man begränsar sig till träd där varje nod förgrenar sig högst två

Tentamen Programmeringsteknik II och NV2 (alla varianter) Skriv bara på framsidan av varje papper.

Programsystemkonstruktion med C++: Övning 2. Karl Palmskog september 2010

Innehåll. Typomvandlingar (casting) Implicita Typomvandlingar. Typomvandlingar (type casts) Explicita, namngivna typomvandlingar (C++-11)

Länkade strukturer, parametriserade typer och undantag

Föreläsning 5. Träd Binära träd Binärt sökträd som ADT Implementering av binärt sökträd Travestera binärt sökträd Sökning Insättning/borttagning

Tentamen Programmeringsteknik II Skrivtid: Hjälpmedel: Java-bok (vilken som helst) Skriv läsligt! Använd inte rödpenna!

Polymorfi. Objektorienterad och komponentbaserad programmering

Kommentarer till Person

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

Innehåll. 1 Funktionsmalllar. 2 Klassmallar. struct Name { string s; //... }; const Name & minimum ( const Name & a, const Name & b) { if(a.s < b.

Träd. Ett träd kan se ut på detta sätt:

Tentamen Datastrukturer (DAT036)

Föreläsning Datastrukturer (DAT036)

5 Arv och dynamisk bindning FIGUR

Övriga byggstenar. Övriga byggstenar. Några tips under programutveckling. Beroenden Pekare till funktioner Typkonvertering

Tentamen EDAF30 Programmering i C++

Arv. Objektorienterad och komponentbaserad programmering

TDIU01 - Programmering i C++, grundkurs

Lösningsförslag till exempeltenta 1

Del3 Klassanvändning, operatorer och pekare Ämnesområden denna föreläsning:

Programmering i C++ EDA623 Mallar. EDA623 (Föreläsning 12) HT / 29

Operatoröverlagring. 1 Definition och deklaration av operatorfunktioner. 2 Anrop av operatorfunktioner

Föreläsning 9 Datastrukturer (DAT037)

SP:PROG3 HT12 Tenta

Föreläsning 3. Stack

Programmering B med Visual C

Sätt att skriva ut binärträd

TENTAMEN CD5250. Objektorienterad programutveckling med C++, 5p. Datum: , Tid: 14:00-19:00

Collections Collections "Envisa" objekt Klasserna Bofstream och Bifstream Definition av metoder i klasserna Bifstream och Bofstream Klassen Streng

Klassen BST som definierar binära sökträd med tal som nycklar och enda data. Varje nyckel är unik dvs förekommer endast en

TDDC76 - Programmering och Datastrukturer

Ett generellt träd är. Antingen det tomma trädet, eller en rekursiv struktur: rot /. \ /... \ t1... tn

Programmering A. Johan Eliasson

TDIU20 - Objektorienterad programmering i c++ - föreläsning 3

Transkript:

TDDI14 Objektorienterad programmering Fö: Binära träd, uttrycksträd 69 Binärt träd TDDI14 Objektorienterad programmering Fö: Binära träd, uttrycksträd 70 Trädtraversering struct Tree_Node Tree_Node(const std::string& value) : data_ value Tree_Node(const std::string& value, Tree_Node* left, Tree_Node* right) : data_ value, left_ left, right_ right root_: Besöka alla noder i trädet på ett systematiskt sätt, olika varianter: djupet först vänster-till-höger eller höger-till-vänster preorder (prefix) inorder (infix) postorder (postfix) bredden först (nivåtraversering) kan göras med hjälp av en kö ~Tree_Node() delete left_; delete right_; std::string data_; ; Tree_Node* left_ nullptr ; Tree_Node* right_ nullptr ; class Tree private: Tree_Node* root_ nullptr ; ; TDDI14 Objektorienterad programmering Fö: Binära träd, uttrycksträd 71 Trädtraversering djupet-först void traverse(tree_node* tree, void (*op)(tree_node*)) if (tree) traverse(tree->left_, op); op(tree); traverse(tree->right_, op); vänster-till-höger inorder (infix) traversering vänster subträd behandlas noden ifråga behandlas höger subträd behandlas operationen som ska utföras på varje nod skickas med i form av en funktionspekare TDDI14 Objektorienterad programmering Fö: Binära träd, uttrycksträd 72 Trädtraversering bredden-först void traverse(tree_node* tree, void (*op)(tree_node*)) if (tree) std::queue<tree_node*> nodes; nodes.push(tree); while (!nodes.empty()) Tree_Node* current_node = nodes.front(); nodes.pop(); vänster till höger if (current_node->left_ ) nodes.push(current_node->left_); if (current_node->right_ ) nodes.push(current_node->right_); op(current_node); nivå för nivå tomma träd ignoreras ett alternativ kan vara att köa även tompekare

TDDI14 Objektorienterad programmering Fö: Binära träd, uttrycksträd 73 Bestämma djupet hos ett träd Innebär också att alla noder kommer att besökas. TDDI14 Objektorienterad programmering Fö: Binära träd, uttrycksträd 74 Trädsökning rekursiv lösning Innebär att följa en specifik väg ner genom trädet. int depth(const Tree_Node* tree) if (tree) return 1 + max(tree->depth(tree->left_), tree->depth(tree->right_)); return 0; rotnoden i ett träd har per definition djupet 0 djupet för en nod är väglängden från roten till noden ett löv har per definition höjd 0 höjden för rotnoden är den längsta väglängden till något av löven Tree_Node* find(std::string x, Tree_Node* tree) if (tree && tree->data_!= x) if (x < tree->data_) return find(x, tree->left_); return find(x, tree->right_); return tree; endast noder utmed en specifik sökväg besöks TDDI14 Objektorienterad programmering Fö: Binära träd, uttrycksträd 75 Trädsökning iterativ lösning Enkel och utan rekursion. Tree_Node* find(std::string, Tree_Node* tree) while (tree && tree->data_!= x) if (x < tree->data_) tree = tree->left_; tree = tree->right_; return tree; iteration är normalt att föredra jämfört med rekursion fall som detta lika enkel algoritm TDDI14 Objektorienterad programmering Fö: Binära träd, uttrycksträd 76 Uttrycksträd Ett tilldelningsuttryck som X = (A + B / C) * (D - E / F) representeras av följande uttrycksträd. = X * + - A / D / B C E F alla operander är löv de finns i samma ordning från vänster till höger i trädet som i uttrycket alla operatorer är inre noder binära operatorer med sina två operander som vänster respektive höger subträd varje subträd representerar ett deluttryck parenteser behövs inte Vilket resultat ger respektive variant av trädtraversering enligt djupet först med följande operation? void print(tree_node* t) cout << t->data_ << ;

TDDI14 Objektorienterad programmering Fö: Undantagsklasser 77 Standardundantag TDDI14 Objektorienterad programmering Fö: Undantagsklasser 78 Standardundantagen exception logic_error domain_error invalid_argument length_error out_of_range future_error runtime_error range_error overflow_error underflow_error system_error ios_base::failure bad_typeid bad_cast bad_weak_pointer bad_exception bad_function_call bad_alloc bad_array_new_length exempelvis kastad av/om: otillåtna funktionsvärden bitset-konstruktor objekts längd överskrids at() funktioner i trådbiblioteket vissa beräkningar bitset::to_long() vissa beräkningar systemrelaterade funktioner ios_base::clear() typeid dynamic_cast std::shared_ptr-konstruktorer brott mot exceptionspecification std::function::operator() new new[] klassen exception är basklass för nästan alla andra standardundantag en del direkta subklasser till exception används för att kasta undantag bad_exception, t.ex. logic_error representerar sådant som beror på fel i programmets logik och i teorin förebyggbart domain_error, invalid_argument, length_error, out_of_range runtime_error representerar sådant som beror på fel utanför programmets kontroll och inte enkelt kan förutses range_error, overflow_error, underflow_error, system_error några undantagsklasser är inte härledda från exception nested_exception, t.ex. TDDI14 Objektorienterad programmering Fö: Undantagsklasser 79 Basklassen exception class exception exception() noexcept; exception(const exception& e) noexcept; ; virtual ~exception(); exception& operator=(const exception& e) noexcept; virtual const char* what() const noexcept; polymorf klass inte abstrakt men bör endast användas som basklass för mer användbara undantagsklasser defaultkonstruktor kopieringskonstruktor virtuell destruktor (kastar per definition inte undantag) kopieringstilldelningsoperator virtuell funktion what() noexcept specificerar att funktionen inte kastar undantag viktigt att undantag inte i sin tur kan kasta nya undantag TDDI14 Objektorienterad programmering Fö: Undantagsklasser 80 Regler för generering av flyttkonstruktor och flyttilldelningsoperator Klassen exception är en bra klass för att ta upp detta. flyttkonstruktor genereras endast om klassen inte har en användardeklarerad kopieringskonstruktor inte har en användardeklarerad kopieringstilldelningsoperator inte har en användardeklarerad flyttilldelningsoperator inte har en användardeklarerad destruktor flyttilldelningsoperator genereras endast om klassen inte har en användardeklarerad kopieringskonstruktor inte har en användardeklarerad flyttkonstruktor inte har en användardeklarerad kopieringstilldelningsoperator inte har en användardeklarerad destruktor exception har en användardeklarerad kopieringskonstruktor, kopieringstilldelningsoperator och destruktor varken flyttkonstruktor eller flyttilldelningsoperator genereras alltså

TDDI14 Objektorienterad programmering Fö: Undantagsklasser 81 En av de direkta subklasserna logic_error Standarden anger endast konstruktorerna men i praktiken definieras logic_error så här. class logic_error : public std::exception explicit logic_error(const std::string& what_arg) : msg_(what_arg) explicit logic_error(const char* what_arg) : msg_(what_arg) virtual const char* what() const noexcept return msg_.data(); private: string msg_; ; defaultkonstruktor genereras inte, eftersom en annan konstruktor har deklarerats kopieringstilldelningsoperator genereras flyttkonstruktor och flyttilldelningsoperator genereras inte, eftersom kopieringskonstruktorn deklareras destruktor kommer att genereras och vara virtual what() överskuggar what() deklarerad i exception TDDI14 Objektorienterad programmering Fö: Undantagsklasser 82 En av subklasserna till logic_error length_error class length_error : public std::logic_error explicit length_error(const std::string& what_arg) : std::logic_error(what_arg) ; explicit length_error(const char* what_arg) : std::logic_error(what_arg) defaultkonstruktor genereras inte, eftersom en annan konstruktor har deklarerats kopieringstilldelningsoperator genereras flyttkonstruktor och flyttilldelningsoperator genereras inte, eftersom en kopieringskonstruktor deklareras destruktor genereras what() ärvs som den är från logic_error TDDI14 Objektorienterad programmering Fö: Undantagsklasser 83 Egendefinierad undantagsklass Härled från exempelvis logic_error class some_error : public std::logic_error explicit some_error(const std::string& what_arg) : std::logic_error(what_arg) ; explicit some_error(const char* what_arg) : std::logic_error(what_arg) Dessutom följande genererade eller ärvda funktionalitet: kopieringskonstruktor kopieringstilldelningsoperator destruktor what() TDDI14 Objektorienterad programmering Fö: Undantagsklasser 84 Hantering av undantag try do cout << "Ange en radposition, avsluta med -1: "; cin >> pos; cout << line.at(pos) << endl; while (pos > -1); catch (const out_of_range& e) cout << e.what() << endl; catch (const exception& e) cout << e.what() << endl; catch (...) cout << "Ett oväntat fel har inträffat" << endl; catch-hanterarna går från specialiserade till mer generella out_of_range exception vad-som-helst

TDDI14 Objektorienterad programmering Fö: Polymorf lista 85 TDDI14 Objektorienterad programmering Fö: Polymorf lista 86 Länkad lista med polymorfa listnoder Konstruerad som en containerklass med två slags listnoder Data_Node lagrar de data som satts i i en lista Null_Node anger slutet av en lista, lagrar inga data Data_Node och Null_Node är härledda från en gemensam basklass List_Node List klass som representerar en ordnad lista lagrar en pekare till Null_Node om listan är tom List_Node abstract Data_Node Null_Node List_Node abstrakt, polymorf basklass för listnoder struct List_Node List_Node() = default; List_Node(const List_Node&) = delete; virtual ~List_Node() = default; List_Node& operator=(const List_Node&) = delete; // används av Null_Node() virtual List_Node* insert(int value) = 0; virtual List_Node* remove(int value) = 0; virtual const List_Node* find(int value) const = 0; Data_Node om listan innehåller ett eller flera värden virtual int length() const = 0; virtual bool empty() const = 0; 1 2 3 4 ; virtual List_Node* clone() const = 0; alla speciella medlemsfunktioner för kopiering elimineras för listnodklasserna endast polymorf kopiering med funktionen clone() tillåts operationer är implementerade med hjälp av polymorfi och rekursion iteratorer ska finnas för List men har utelämnats i exemplen (motsvarande uppgift ska göras i laboration Listan) TDDI14 Objektorienterad programmering Fö: Polymorf lista 87 Data_Node nodtyp för att lagra ett insatt värde TDDI14 Objektorienterad programmering Fö: Polymorf lista 88 Null_Node markerar slutet på en lista struct Data_Node : public List_Node Data_Node(int value, List_Node* next) : data_ value, next_ next Data_Node(const Data_Node&) = delete; ~Data_Node() delete next_; Data_Node& operator=(const Data_Node&) = delete; Data_Node* insert(int value) override; List_Node* remove(int value) override; const List_Node* find(int value) const override; int length() const override; bool empty() const override; struct Null_Node final : public List_Node Null_Node() = default; Null_Node(const Null_Node&) = delete; ~Null_Node() = default; Null_Node& operator=(const Null_Node&) = delete; Data_Node* insert(int value) override; Null_Node* remove(int value) override; const List_Node* find(int value) const override; int length() const override; bool empty() const override; // används av List ; Data_Node* clone() const override; int data_; List_Node* next_; ; Null_Node* clone() const override; Observera i den givna koden är medlemsfunktioner som är enkla definierade i klassen. Observera i den givna koden är alla medlemsfunktioner definierade i klassen.

TDDI14 Objektorienterad programmering Fö: Polymorf lista 89 List en containerklass TDDI14 Objektorienterad programmering Fö: Polymorf lista 90 En containerklass ska alltid ha swap-funktioner class List List() : list_ new Null_Node List(const List& other) : list_ copy(other.list_) List(List&& other) noexcept : List() swap(other); ~List() delete list_; List& operator=(const List& rhs) &; List& operator=(list&& rhs) & noexcept; void insert(int value); void remove(int value); bool member(int value) const; int length() const; bool empty() const; void clear(); void swap(list& other) noexcept; // Iteratorer private: List_Node* list_; // delegering till List() // Även icke-medlem-swap finns Medlem void List::swap(List& other) std::swap(list_, other.list_); Icke-medlem void swap(list& a, List& b) a.swap(b); Argumenten till std::swap() är pekare standarden garanterar att undantag inte kastas. ; static List_Node* copy(const List_Node* p); TDDI14 Objektorienterad programmering Fö: Polymorf lista 91 Radera en listas innehåll TDDI14 Objektorienterad programmering Fö: Polymorf lista 92 List konstruktorer och destruktor void List::clear() if (!empty()) Data_Node* garbage = dynamic_cast<data_node*>(list_); Data_Node* p = garbage; while (!dynamic_cast<null_node*>(p->next_)) p = dynamic_cast<data_node*>(p->next_); // p pekar på datanoden direkt före null-noden list_ = p->next_; p->next_ = nullptr; delete garbage; // pekare till datanoderna i listan // behåll null-noden // länka ur den // radera alla datanoder Defaultkonstruktor List() : list_ new Null_Node initierar listan till tom lista en Null_Node Kopieringskonstruktor List(const List& other) : list_ copy(other.list_) kopierar listan av noder i other Flyttkonstruktor List(List&& other) noexcept : List() swap(other); initierar det nya List-objektet till tom lista och byter sedan innehåll med other delegerar initiering av list_ till List() innan bytet med swap() ska deklareras noexcept list_ har typen List_Node* måste typomvandlas till Data_Node* för att kunna initiera garbage datamedlemmen next_ har typen List_Node* måste typomvandlas till Data_Node* för att kunna tilldelas p inuti while-satsen typomvandlingen i while-satsen styruttryck kontrollerar om nästa nod är null-noden Destruktor ~List() delete list_; rekursiv destruering av noderna i listan när detta är gjort upphör List-objektet att existera

TDDI14 Objektorienterad programmering Fö: Polymorf lista 93 List tilldelningsoperatorer Kopieringstilldelningsoperator List& List::operator=(const List& rhs) & List rhs.swap(*this); return *this; ref-qualifier & tilldelning kan endast användas på vänsterargument som är lvalue (ska vara en variabel) implementeras med idiomet skapa en temporär och byt undantag kan kastas när det temporära objektet ska initieras startk undantagssäkert dock ska deklareras med ref-qualifer & Flyttilldelningsoperator List& List::operator=(List&& rhs) & noexcept clear(); swap(rhs); return *this; vänsterargumentets innehåll raderas blir tom lista vänsterargumentet och högerargumentet byter innehåll högerargumentet blir en tom lista ska deklareras med ref-qualifer & och noexcept TDDI14 Objektorienterad programmering Fö: Polymorf lista 94 Intern kopiering av lista List_Node* List::copy(const List_Node* p) return p->clone(); // clone() kan kasta undantag Data_Node* Data_Node::clone() const // Att göra Om undantag kastas här läcker minnet för den redan kopierade svansen! return new Data_Node data_, next_->clone() ; Null_Node* Null_Node::clone() const // Att göra Om undantag kastas här läcker något minne? return new Null_Node; Obsererva override används inte utanför klassen. TDDI14 Objektorienterad programmering Fö: Polymorf lista 95 Listans längd int List::length() const return list_->length(); TDDI14 Objektorienterad programmering Fö: Polymorf lista 96 Finns ett visst värde i listan? bool List::member(int value) const return list_->find(value)!= nullptr; int Data_Node::length() const return 1 + next_->length(); int Null_Node::length() const return 0; const List_Node* Data_Node::find(int value) const if (data_ == value) return this; return next_->find(value); const List_Node* Null_Node::find(int) const return nullptr; // Deklarera ej namn för parameter

TDDI14 Objektorienterad programmering Fö: Polymorf lista 97 Är listan tom? bool List::empty() const return list_->empty(); TDDI14 Objektorienterad programmering Fö: Polymorf lista 98 Sätta in ett värde i listan void List::insert(int value) list_ = list_->insert(value); bool Data_Node::empty() const return false; bool Null_Node::empty() const return true; Data_Node* Data_Node::insert(int value) if (value < data_) return new Data_Node value, this ; next_ = next_->insert(value); return this; // Om undantag kastas läcker minne? Data_Node* Null_Node::insert(int value) return new Data_Node value, this ; // Om undantag kastas läcker minne? TDDI14 Objektorienterad programmering Fö: Polymorf lista 99 Ta bort värde ur listan (det först hittade) void List::remove(int value) list_ = list_->remove(value); List_Node* Data_Node::remove(int value) if (value == data_) List_Node* next next_ ; next_ = nullptr; delete this; return next; next_ = next_->remove(value); return this; // Rekursiv destruktor noden måste länkas ur helt innan destruering Null_Node* Null_Node::remove(int) return this; // Värdet fanns inte