Computing with C# and the .NET Framework Chapter 12 Data Structures
Recursion Recurs inside of itself public void Travel(int start, int finish) { if (start < finish) { TakeOneStep(start); // one more step Travel(start + 1,finish); // increase start } // and do the rest }
Binary Search public static int Search(int [ ] data, int key, int left, int right) { if (left <= right) { int middle = (left + right)/2; if (key == data[middle]) // check middle element return middle; // return index when found else if (key < data[middle]) // search left half recursively return Search(data,key,left,middle - 1); else // search right half recursively return Search(data,key,middle + 1,right); } return -1;
Figure 12.1 Trace of a binary search for 78 in the data entry Search(data, 78, 0, 12) Middle = (0+12)/2 = 6 78 > data[6] // data[6] = 56 // search index 7 to index 12. Search(data, 78, 7, 12) Middle = (7+12)/2 = 9 78 < data[9] // data[9] = 123 // search index 7 to index 8. Search(data, 78, 7, 8) Middle = (7+8)/2 = 7 78 == data[7] // data[7] = 78 // return the index 7 to the caller. Figure 12.1 Trace of a binary search for 78 in the data entry
Merge Sort public static void Sort (int [ ] data, int left, int right) { if (left < right) { int middle = (left + right)/2; Sort(data,left,middle); // sort the left half Sort(data,middle + 1,right); // sort the right half Merge(data,left,middle,middle + 1,right); // merge the left and right }
Figure 12.2 Merging two sorted arrays First Array Second Array Merged Array {2, 5, 7, 8} {3, 4, 9, 10} {2} {5, 7, 8} {2, 3} {4, 9, 10} {2, 3, 4} {9, 10} {2, 3, 4, 5} {7, 8} {2, 3, 4, 5, 7} {8} {2, 3, 4, 5, 7, 8} {} {2, 3, 4, 5, 7, 8, 9, 10} Figure 12.2 Merging two sorted arrays
124 37 45 null Figure 12.3 A linked list
Figure 12.4 Adding 40 to the linked list of Figure 12.3 124 37 45 null 40 Figure 12.4 Adding 40 to the linked list of Figure 12.3
Figure 12.5 The operation of LinkedList class public LinkedList() Constructs an empty linked list, with the head, previous, and current nodes null. public boolean IsEmplty() Returns true if the list is empty and false otherwise. public void Insert(Object o) Creates a node containing the object o, inserting it before the current element. public void Remove() Removes the current element. public Object GetData() Gets the data field from the current element. Returns null if the current element is null. public boolean AtEnd() Returns true if the current element is null and false otherwise. public void Advance() If current is not null, advances the precious and current references. public void Reset() Resets the current reference to refer to the head of the list. public void Display() Prints each element of the list on a separate line. Figure 12.5 The operation of LinkedList class
Stack LIFO Last In First Out Push // Add value to top of stack Pop // Remove and return top IsEmpty Top // Return top value IsFull
Figure 12.6 A stack growing from left to right 15 7 12 top Figure 12.6 A stack growing from left to right
top Figure 12.7 An empty stack
15 7 12 4 5 24 top Figure 12.8 A full stack
Figure 12.9 Pushing 4 into the stack of Figure 12.6 15 7 12 4 top Figure 12.9 Pushing 4 into the stack of Figure 12.6
Figure 12.10 Popping the stack of Figure 12.9 15 7 12 4 top Figure 12.10 Popping the stack of Figure 12.9
Postfix + 5 6 prefix 5 + 6 infix 5 6 + postfix With postfix expressions do not need () 3 + 4 * 5 becomes 3 4 5 * +
Postfix evaluation do { Read the next character; if (next character is a digit) Convert the digit to an integer and push the integer on the stack; else if (next character is an operator) { Pop two operands from stack; Perform the operation; Push the result onto the stack; } } while (more characters); Display the top of the stack;
Figure 13.11 Evaluating the expression 7 8 + 4 5 + * (1/2) Read ‘7’ Push the integer 7 7 Read ‘8’ Push the integer 8 7 8 Read ‘+’ Pop 8 and pop 7 Empty Add. Getting 15 Push 15 15 Read ‘4’ Push the integer 4 15 4 Read ‘5’ Push the integer 5 15 4 5 Figure 13.11 Evaluating the expression 7 8 + 4 5 + * (1/2)
Figure 13.11 Evaluating the expression 7 8 + 4 5 + * (2/2) Read ‘+’ Pop 5 and pop 4 15 Add. Getting 9 Push 9 15 9 Read ‘*’ Pop 9 and pop 15 Empty Multiply, giving 135 Push 135 135 Pop 135 and display it. Figure 13.11 Evaluating the expression 7 8 + 4 5 + * (2/2)
Queues FIFO First In First Out IsEmpty IsFull Add // adds to the rear Remove // removes from the front Head // returns front element
Figure 12.12 A queue containing three elements 4 17 6 back front Figure 12.12 A queue containing three elements
Figure 12.13 A circular queue 4 17 back 6 front Figure 12.13 A circular queue
ArrayList new ArrayList() // starts at 16, doubles when full Add // adds at end Insert // inserts at a position Contains IndexOf Capacity property // can hold Count property // does hold
The foreach statement Retrieves elements of a collection Enumeration e = v.elements() // v is a Vector For example, if v is an ArrayList of String foreach (String s in v) Console.WriteLine(s) Will display each String in v
Timing The Environment class has a TickCount property that gives the number of milliseconds since the computer was last started. Find TickCount before and after computation and subtract to get the time elasped.
Hash tables Maps keys to values using a hash function Object class has GetHashCode method Override to provide GetHashCode for derived class String overrides GetHashCode method which returns integer hash code for s
Hash functions Hashtable uses hash function to enter keys. String river name maps to integer index Example: Table size 37 Hash function: Sum of ASCII Find remainder mod 22 to get table index Nile 78+105+108+101=392 392 % 37 = 22
Figure 12.5 Rivers of the world and their lengths (in miles) Amazon 4000 Indus 1800 Chang (Yangtze) 3964 Mekong 2600 Colorado 1450 Mississippi 2340 Columbia 1243 Missouri 2315 Congo 2718 Niger 2590 Danube 1776 Nile 4160 Euphrates 1700 Rio Grande 1900 Ganges 1560 Volga 2290 Huang (Yellow) 3395 Figure 12.5 Rivers of the world and their lengths (in miles)
Using a Hashtable Hashtable rivers = new Hashtable(37); rivers.add(names[i], length[i]) // associates length with name foreach(DictionaryEntry entry in rivers) // loop through hash table // entry.Key and entry.Value retrieve entry
Comparisons To test for membership in a collection objects need to override bool Equals(Object o); int GetHashCode(); Name class does not, so it cannot be added to a collection, but NewName does
A Name class from Chapter 6 using System; public class Name { String first; char initial; String last; public Name(String f, String l) { first = f; last = l; } public Name(String f, char i, String l) : this(f,l) { initial = i; public String ToString() { if (initial == '\u0000') return first + " " + last; else return first + " " + initial + " " + last; A Name class from Chapter 6
Figure 12.16 Two Name instances Name president = new Name(“George”, “Washington”); Name first = new Name(“George”, “Washington”); president “George”, “Washington” first “George”, “Washington” Figure 12.16 Two Name instances
The IComparable interface Need to compare objects to keep them sorted public int CompareTo(Object object); SortedList requires IComparable keeps items in sorted order NewName does not, but NewOrderedName does implement IComparable
Figure 12.17 The Towers of Hanoi puzzle