Länkade strukturer Antag att vi vill lagra ett antal objekt med någon form av inbördes relation. Enklaste strukturen är en linjär lista: a first b c d e f last Alla elementen utom första har en föregångare och alla utom det sista har en efterföljare. Exempel: Objekt som man vill ha sorterade på någon viss egenskap, olika former av köer. (3 maj 2015 – Länkade listor 1 ) Linjär lista i array eller arraylist 0 a b 2 1 c 3 4 d 5 e f last first Fördel: Snabb access till element i viss position (index) Nackdel: Krångligt (”dyrt”) att ta bort eller lägga till element eftersom element måste flyttas, arrayutrymmet måste omallokeras. Obs: Gäller även arraylist även om dess API stödjer det (3 maj 2015 – Länkade listor 2 ) Linjära listor med länkar Låt varje objekt peka ut sin efterföljare: a b c d e f last first Fördel: Mer dynamiskt. Element kan läggas in och tas bort var som helst utan att andra element behöver flyttas. Nackdel: Svårt (”dyrt”) att hitta element i viss position (3 maj 2015 – Länkade listor 3 ) Klasser för länkade listor Java har en standardklass (LinkedList) för länkade listor men vi skall göra en egen. Varför? Jo, för att illustrera tekniker att hantera dynamiska strukturer. Dessutom: Bra övningar i rekursivt tänkande! En lista är antingen tom (dvs består av 0 element) eller består av ett element följt av en lista. (3 maj 2015 – Länkade listor 4 ) Exempel: Klassen List Klassen List skall I hantera länkade listor med heltal i listnoderna, I hålla listorna sorterade (underlättar vissa operationer) och I se till att varje lista bara innehåller ett givet värde en gång. Med andra ord: Klassen representerar mängder med heltal Anmärkning: Trots att listorna bara innehåller heltal är teknikerna och algoritmerna generella. (3 maj 2015 – Länkade listor 5 ) Exempel: Klassen List forts En enkellänkad lista med heltal kan åskådliggöras så här: 3 5 17 ..... De enskilda elementen i listan representeras som objekt ur klassen Node: Observera hur klassen Node innehåller ett objekt ur klassen Node — en rekursiv definition! 42 class Node { int data; Node next; ... } (3 maj 2015 – Länkade listor 6 ) Exempel: Klassen List forts För att hålla reda på listan och gör man typiskt en annan klass: ListNode List 3 5 17 ..... 42 first last public class List { private Node first; private Node last; // Optional (3 maj 2015 – Länkade listor 7 ) Exempel: Klassen List forts Klassen Node rör bara listans interna organisation. Vi placerar den som en private inre klass i klassen List: public class List { private static class Node { int data; Node next; Varför static? Node(int d, Node n) { data = d; next = n; } } (3 maj 2015 – Länkade listor 8 ) Klassen List: toString ListNode List 3 5 17 ..... 42 first last public String toString() { return "[" + toString(first) + "]"; } (3 maj 2015 – Länkade listor 9 ) Klassen List: toString forts 3 5 17 ..... 42 private static String toString(Node n) { if (n==null) { return ""; } else { return n.data + toString(n.next); } } (3 maj 2015 – Länkade listor 10 ) Klassen List: insert 3 5 1 17 8 42 53 public void insert(int k) { first = insert(k, first); } ’ (3 maj 2015 – Länkade listor 11 ) Klassen List: insert forts 3 1 5 17 8 42 53 private static Node insert(int k, Node n) { if (n==null || k<n.data) { return new Node(k, n); } else if (k>n.data) { n.next = insert(k, n.next); } return n; } (3 maj 2015 – Länkade listor 12 ) Klassen List: remove 3 5 17 42 public void remove(int k) { first = remove(k, first); } (3 maj 2015 – Länkade listor 13 ) Klassen List: remove forts 3 5 17 42 private static Node remove(int k, Node n) { if (n==null || k<n.data) throw new ListException("remove: No such element in list: " + k); else if (k==n.data) return n.next; else { n.next = remove(k, n.next); return n; } } (3 maj 2015 – Länkade listor 14 ) Klassen List: copy public List copy() { return new List(copy(first)); } // Private constructor private static Node copy(Node n) { if (n==null) return null; else return new Node(n.data, copy(n.next)); } (3 maj 2015 – Länkade listor 15 ) Några alternativa representationer Dubbellänkat: 3 5 17 42 Kan finna både efterföljare och föregångar på O(1) tid (3 maj 2015 – Länkade listor 16 ) Några alternativa representationer Cirkulärt: 3 5 17 42 Hittar både första och sista på O(1) tid! (3 maj 2015 – Länkade listor 17 ) Några alternativa representationer Dubbellänkat cirkulärt: 3 5 17 42 Enkellänkat ofta enklast och effektivast! (3 maj 2015 – Länkade listor 18 )
© Copyright 2024