190 likes | 204 Views
Examples of class: Recursive data structures. Instructor: Mainak Chaudhuri mainakc@cse.iitk.ac.in. Recursive data structures. Refers to a “connected” set of similar objects Object A “connects” or “refers” to object B
E N D
Examples of class: Recursive data structures Instructor: Mainak Chaudhuri mainakc@cse.iitk.ac.in
Recursive data structures • Refers to a “connected” set of similar objects • Object A “connects” or “refers” to object B • For example, in a list of integers you can imagine each integer in the list as an object and each object connects to its next object thereby forming a list • The structure is called recursive because an object of type class A connects to another object of the same class type • Very important to build complex connected structures e.g., a network of cities where a “connection” could mean rail or road
List structure • Why not just an array? • Basic operations needed on a list: search, insertion, deletion • All these are time consuming in arrays e.g., searching is O(n), insertion at head is O(n), and deletion from head is also O(n) • With lists, arbitrary insertion and deletion can be made in O(1) time; searching is still costly (we will discuss techniques to improve it on average and in the worst case) • Insertion and deletion involve changing a few references (independent of n)
List structure • Consider insertion sort • For each element, we compared it with all elements on its left until a comparison failed and then shifted up all the elements on the right to make a hole for insertion • If the numbers are stored in a list, the last shift-up step can be completely avoided • Just insert one element and delete another: O(1) • Recall that with a reverse-sorted array, the number of comparisons is minimum while with a sorted array, the number of comparisons is maximum • But former spends more time in shift-up leading to both cases requiring roughly the same amount of time • With a list implementation, the first case will indeed be the fastest
List structure public class IntegerList { private int data; private IntegerList next; public IntegerList (int x, IntegerList rest) { data = x; next = rest; } // next slide
List structure public IntegerList (int x) { data = x; next = null; } public int GetHead () { return data; } // next slide
List structure public IntegerList GetBody () { return next; } public int Length () { if (next==null) return 1; return (1 + GetBody().Length()); } public int GetTail () { if (next==null) return data; return GetBody().GetTail(); }
List structure public IntegerList Search (int x) { if (data==x) return this; if (next==null) return null; return GetBody().Search(x); } public int ExtractElement (int index) { // This is slower compared to array if (index==0) return data; if (next==null) { System.out.println (“Query index too large!”); return -1; } return GetBody().ExtractElement (index-1); }
List structure public void Enqueue (int x) { if (next==null) { next = new IntegerList (x); } else { GetBody().Enqueue(x); } } // next slide
List structure public IntegerList Dequeue () { return next; } public IntegerList Reverse () { if (next==null) return this; IntegerList temp = GetBody().Reverse(); temp.Enqueue (data); return temp; } // next slide
List structure public void SetBody (IntegerList x) { next = x; }
List structure public void Print () { if (next==null) { System.out.println (data); } else { System.out.print (data + “, ”); GetBody().Print(); } } // next slide
List structure public IntegerList SearchAndDelete (int x) { // return the new head of the list IntegerList temp = this; IntegerList prev = null; while ((temp != null) && (temp.GetHead() != x)) { prev = temp; temp = temp.GetBody(); } // next slide
List structure if (temp != null) { // found x if (prev == null) { // first one is x return temp.GetBody(); // new head of list } else { prev.SetBody (temp.GetBody()); return this; } } else { // did not find x return this; } } // next slide
List structure public IntegerList SortedInsert (int x) { // return the new head of the list IntegerList temp = this; IntegerList prev = null; IntegerList newBorn = new IntegerList (x); while ((temp != null) && (temp.GetHead() < x)) { prev = temp; temp = temp.GetBody(); } // next slide
List structure if (temp != null) { if (prev == null) { // Insert at head newBorn.SetBody(this); return newBorn; } else { // Insert in middle prev.SetBody(newBorn); newBorn.SetBody(temp); return this; } } // next slide
List structure else { // Insert at end prev.SetBody(newBorn); return this; } } } // end class • Need for maintaining a tail reference • Could enqueue at end without traversing the entire list
List structure class ListBuilder { public static void main (String a[]) { IntegerList iL = new IntegerList (5); iL = new IntegerList (6, iL); iL = new IntegerList (-2, iL); iL.Enqueue (13); System.out.println (“Length: ” + iL.Length()); System.out.println (“Position 2: ” + iL.ExtractElement (2)); iL.Print (); // next slide
List structure iL = iL.Reverse(); iL.Print(); iL = iL.SearchAndDelete(-2); iL.Print(); iL = iL.SortedInsert(10); iL.Print(); } }