210 likes | 338 Views
Data Structures. Mugurel Ionu ț Andreica Spring 2012. Grading. Activity during the Laboratory – 10% Homework Assignments – 40% 4 homework assignments – 10% each Exam – 50% [optional] Course Tests (bonus: up to 10% of the final grade; maybe less)
E N D
Data Structures Mugurel Ionuț Andreica Spring 2012
Grading • Activity during the Laboratory – 10% • Homework Assignments – 40% • 4 homework assignments – 10% each • Exam – 50% • [optional] Course Tests (bonus: up to 10% of the final grade; maybe less) • Must obtain at least 25% of the final grade (from Lab Activity + Homework Assignments + Course Tests) in order to be allowed to participate in the exam
Course Topics • Introduction to C++ Programming • Abstract Data Type – concept • Stack • Queue • Linked Lists • Graphs • Hash Tables • Trees (Binary Trees, Binary Search Trees, Balanced Binary Search Trees) • Heaps • Disjoint Sets • Other Advanced Topics [ if time allows ] – not for exam
Introduction to C++ Programming • Similar to C Programming • Inclusion of headers • Definition of types/classes • Declaration of global variables • Definition of functions • The main function • Extra C++ Concepts: • C++ classes • May contain both variables (fields) and functions with public/private/protected access specifications • Inheritance (only very basic aspects – the rest is handled in the OOP course) • Templates (generalized classes, functions, variables, etc.) • Usually used for specifying data types
Common C/C++ Types • Basic types • int • char • float • double • void – only for function return values • Structured data types • struct s { int x; char y[2], z; double w }; • Classes • Pointer types • int*, int**, ... • char*, char**, ... • float*, float**, ... • double*, double**, ... • void*, void**, ... • Pointers to structs • Pointers to classes • Defining (multidimensional) arrays • int v[100] // a static array named v with 100 elements, indexed from 0 to 99 • int u[100][150], v[10][20][30], w[10][20][30][40], ... • char u[100], v[10][20], w[10][20][30], ... • float u[100], v[10][20], w[10][20][30], ... • struct s u[100], v[10][20], w[10][20][30], ... • ...
Classes in C++ • class class_name { access_specifier_1: members; methods; access_specifier_2: members; methods; ... constructor // same name as the class destructor // ~class_name } • Access specifier = public / private / protected • A class may contain variables and methods
Sample C++ Program with Classes MyClass(int value) { printf("Calling the constructor\n"); x = value; cnt = 0;} ~MyClass() { printf("Calling the destructor\n");} }; int main() { int i; MyClass c(7); printf("%d\n", c.getX()); c.setX(19); c.y = 17; printf("%d\n", c.getX()); for (i = 0; i < 10; i++)c.addToV((double) i); for (i = 9; i >= 0; i--) printf("%.3lf\n", c.getFromV(i)); return 0; } #include <stdio.h> class MyClass { private: int x, cnt; double v[100]; public: int y; void setX(int value) { x = value;} int getX() { return x;} void addToV(double value) { v[cnt] = value; cnt++;} double getFromV(int pos) { return v[pos];}
Abstract Data Type • A collection of axioms + operations • Operations = what actions can be performed upon the data type (implemented as functions in C/C++) • for each operation we know: • its name • its arguments (types and, possibly, names) • its return type • Axioms specify connections between operations (i.e. the operations are related to one another) • Does not contain information regarding the implementation of the operations • Similar to a Java interface (except that only the operations are specified in an interface and no axioms)
Abstract Data Types - examples • Stack • Operations: push, pop, peek, isEmpty • Axioms: a pop() call returns the argument x of the most recent push(x) operation called on the data type for which no corresponding pop() has been called before (or an error, otherwise) • Queue • Operations: enqueue, dequeue, peek, isEmpty • Axioms: a dequeue() call returns the argument x of the oldest enqueue(x) call for which no corresponding dequeue() was called (or an error, otherwise)
From Abstract Data Types to Data Structures • Data structures will be initially handled as abstract data types • First we will specify the operations and axioms (many times, the axioms will be given implicitly) • Then we will discuss possible implementations (occasionally more than just one) • Data structures store elements • Sometimes, the elements may have any type • Other times, the elements must obey some specific properties (e.g. they must be comparable) • In order to store any type of elements => we will use class templates (in C++)
Class Templates • template<typename T> class class_name { ... } • A normal class definition will be prefixed by template<typename T> • The type T can now be used as a valid type within the class • we can have variables, function arguments and function return values of type T • The class class_name is parameterized with the type T • Most of the times: T=the type of the elements stored by the data structure • Similar to Java generics
Class Templates - Example int main() { MyGenericContainer<int> c1(7); printf("%d\n", c1.getPrivateObject()); c1.setPrivateObject(9); printf("%d\n", c1.getPrivateObject()); MyGenericContainer<double> c2(7.9); printf("%.3lf\n", c2.getPrivateObject()); c2.setPrivateObject(9.902); printf("%.3lf\n", c2.getPrivateObject()); struct mystruct a; a.x = 3;a.y[4] = 'z'; a.y[5] = 90; a.z = 90.234; MyGenericContainer<struct mystruct> c3(a); printf("%.3lf\n", (c3.getPrivateObject()).z); a.z++; c3.setPrivateObject(a); printf("%.3lf\n", (c3.getPrivateObject()).z); return 0; } #include <stdio.h> template<typename T> class MyGenericContainer { private: T privateObject; public: void setPrivateObject(T value) { privateObject = value; } T getPrivateObject() { return privateObject; } MyGenericContainer(T value) { privateObject = value; } }; struct mystruct { int x; char y[32]; double z; };
Recursion • Very important in the implementation of several data structures (usually the “tree-like” ones) • E.g. in order to perform an operation on a tree node, the same operation must first be called on the node’s children • Simple functions: • Factorial • Fibonacci • Sorting functions (with good time complexities) • Merge sort • Quick sort
The Fibonacci Sequence #include <stdio.h> #define NMAX 50 int numCalls = 0; int memoFib[NMAX]; int fibo(int n) { numCalls++; if (memoFib[n] >= 0) return memoFib[n]; if (n <= 1) return (memoFib[n] = 1); else return (memoFib[n] = fibo(n-1) + fibo(n-2)); } int main() { int i, n; scanf("%d", &n); for (i = 0; i <= n; i++)memoFib[i] = -1; printf("Fibonacci(%d)=%d\n", n, fibo(n)); printf("Total number of calls=%d\n", numCalls); return 0; } • F(0)=F(1)=1 • F(n≥2)=F(n-1)+F(n-2) • 1, 1, 2, 3, 5, 8, 13, ... #include <stdio.h> int numCalls = 0; int fibo(int n) { numCalls++; if (n <= 1) return 1; else return fibo(n-1) + fibo(n-2); } int main() { int n; scanf("%d", &n); printf("Fibonacci(%d)=%d\n", n, fibo(n)); printf("Total number of calls=%d\n", numCalls); return 0; } V2 V1
The Fibonacci Sequence (cont.) • V1 • Fibonacci(20) = 10946 • numCalls = 21891 • Tree of Calls for V1 (n=4) : • V2 • Fibonacci(20) = 10946 • numCalls = 39 • Tree of Calls for V2 (n=4) :
The Fibonacci Sequence (cont.) #include <stdio.h> int fibo(int n) { int i, fminus1, fminus2, fcurr; fminus1 = 1; fcurr = 1; i = 1; while (i < n) { i++; fminus2 = fminus1; fminus1 = fcurr; fcurr = fminus1 + fminus2; } return fcurr; } int main() { int i, n; scanf("%d", &n); printf("Fibonacci(%d)=%d\n", n, fibo(n)); return 0; } • What if we change the order of the calls fibo(n-1) and fibo(n-2) ? • We use: fibo(n-2) + fibo(n-1) • Does the resut change ? (V1, V2) • Does the total number of calls change ? (V1, V2) • A non-recursive function on the right V3
Generic Merge Sort • Explanations on the blackboard • See source code afterwards
Generic QuickSort • Quicksort(int pstart, int pstop): sort all the elements between pstart and pstop (inclusively) from the array of elements • Choose a pivot among the elements between pstart and pstop • The pivot should be smaller than the maximum element within that range • Repeatedly swap the elements between pstart and pstop until all the elements <= pivot are located to the left of all the elements > pivot
Generic QuickSort (cont.) • Use two indices, i and j • Initially, i=pstart and j=pstop • During the swapping phase: all the elements to the left of i are <= pivot and all the elements to the right of j are > pivot • While (i<=j): • If (v[i] <= pivot) i++; • Else if (v[j] > pivot) j--; • Else: • Swap v[i] and v[j] • i++; • j--;
Generic QuickSort (cont.) • Then, recursively call: • Quicksort(pstart, i-1) • i.e. sort all the elements <= pivot • Quicksort(i, pstop) • i.e. sort all the elements > pivot • See source code
Generic QuickSort (cont.) • Example: 7 9 2 4 7 3 8 2 1 • Choose pivot=3 • i=0, j=8, 7 9 2 4 7 3 8 2 1 • i=1, j=7, 1 9 2 4 7 3 8 2 7 • i=2, j=6, 1 2 2 4 7 3 8 9 7 • i=3, j=6, 1 2 2 4 7 3 8 9 7 • i=3, j=5, 1 2 2 4 7 3 8 9 7 • i=4, j=4, 1 2 2 3 7 4 8 9 7 • i=4, j=3, 1 2 2 37 4 8 9 7