Abstract Data Type (ADT) Abstract Data Type (ADT) • An Abstract Data Type (ADT) is a data structure with a set of operations – Operations specify how the ADT behaves, but does not reveal how they are implemented – In many cases, there are more than one way to implement an ADT • In this course we will cover lots of ADTs – – – – – Lists Stacks Queues Trees & Search Trees Hash Tables & Tries 2 Abstract Data Type (ADT) - more • An Abstract Data Type (ADT) is a data structure with a set of operations Attributes (ADT State) … … Operations (ADT Methods) Operation1(…) Operation2(…) Operation3(…) … … … 3 • What is a list? List ADT – An ordered sequence of elements A1, A2, …, AN – Elements may be of arbitrary, but the same type (i.e., all ints, all doubles etc.) • Common List operations are: – – – – – – – – Insert(ElementType E, Position P) Delete(Position P) Find(ElementType E) IsEmpty() – Returns true if the list is empty First() – Returns the first element Last() – Returns the last element Kth(Position K) – Returns the Kth element Length() – Returns the length of the list 4 Array List ADT ArrayList ADT #define MAX_SIZE 100; typedef struct ArrayList { int elements[MAX_SIZE]; int noOfElements; // Constructor: // Make empty list ArrayList(){ noOfElements = 0; } // end-ArrayList //public ArrayList (); // Constructor void Insert(int e, int pos); void Delete(int pos); int Find(int e); bool IsEmpty(); int First(); int Last(); int Kth(int pos); int Length(); }; 5 The Abstract Data Type (ADT) The concept of abstraction means: • We know what a data type can do • How it is hidden for the user With an ADT users are not concerned with how the task is done but rather with what it can do. 6 ADT: Example • The program code to read/write some data is ADT. It has a data structure (character, array of characters, array of integers, array of floating-point numbers, etc.) and a set of operations that can be used to read/write that data structure. 7 The Abstract Data Type (ADT) The Abstract Data Type (ADT) is: • A data declaration packaged together with the operations that are meaningful for the data type. • In other words, we encapsulate the data and the operations on the data, and then we hide them from the user. Declaration of data Declaration of operations Encapsulation of data and operations 8 The Abstract Data Type (ADT) • All references to and manipulation of the data in a structure must be handled through defined interfaces to the structure. • Allowing the application program to directly reference the data structure is a common fault in many implementations. • We must hide the implementation from the user 9 ADT Operations • Several classes of operations are required in order to effectively used ADT. 1. Constructors – used to create instances of the data type. 2. Destructors – used to destroy an instance of the data type 3. Accessors – used to access attributes of the data type. (Such as “get” functions) 4. Modifiers – used to modify attributes of the data type. (Such as “set” functions) Object-oriented languages provide some of this functionality within the language. In C you must do it yourself. 11 Design While we’ve defined an ADT interface, we can’t just start coding quite yet. There are more design decisions to be made before writing code for the implementation. A common error among programmers is to not place enough emphasis on the design step. This is the difference between a “programmer” and an “analyst”. Fraction ADT Design: Data Analysis begins with the idea that all the operations will be acting on Fractions that have some internal representation. The representation shall be shared among all the operations. Each operation is responsible for maintaining your design rules regarding the representation of Fraction information. typedef enum{ POS, NEG } SignType; typedef Fraction { //private: // data members int numerator; /* numerator and denominator are declared as */ int denominator; /* int to simplify the algorithms, but they */ SignType sign; /* will always be stored >= 0 */ // public: // member functions would follow //private: // utility functions would follow }; All operations must preserve these rules. Fraction ADT Variables • Now that we’ve decided how to represent the value of a fraction, how are we going to declare variables whose values are fractions? Fraction f1, f2; Fraction ADT Algorithms • You are responsible for designing algorithms that implement all the operations. What process must you follow to implement the operations? a c ad + bc Sum: + = b d bd Product: a c ac * = b d bd then, reduce then, reduce Subtraction involves adding the opposite, and Division involves multiplying by the reciprocal. Fraction ADT Algorithms • Reducing a fraction involves finding the Greatest Common Divisor, and then dividing all the terms by that amount. Euclid’s Algorithm: if x < y, then swap x and y While y is not zero remainder = x mod y x=y y = remainder When you’re done, x is the GCD. Accessors /*********** Accessors **************/ int getNumerator(); int getDenominator(); char getSign(); Modifiers /********** Modifiers ***********/ void setNumerator(int); void setDenominator(int); void setSign(char); void reduceFract();