Chap 2 2 Intro To Data Structures ADTs
- Slides: 59
Chap. 2 2. Intro. To Data Structures & ADTs – C-Style Types • Goal: to organize data • Criteria: to facilitate efficient – storage of data – retrieval of data – manipulation of data • Design Issue: – select and design appropriate data types. (This is the real essence of OOP. ) 1
Examples – Factors to Consider Lab 2 A Airline Reservations Trans-Fryslan Airlines (pp. 30 -31) Attempt 1: enum Seat. Status {OCCUPIED, UNOCCUPIED}; Seat. Status seat 1, seat 2, . . . , seat 10; Horrible algorithms for the basic operations! Attempt 2: const int MAX_SEATS = 10; // upper limit on number of seats enum Seat. Status {OCCUPIED, UNOCCUPIED}; typedef Seat. Status Seat. List[MAX_SEATS]; Seat. List seat; Nice algorithms for the basic operations! Tradeoff: simplicity of data organization « simplicity/elegance of algorithms Simple (unsophisticated data structure) may require much work for processing data. More complex data organization may yield nicer algorithms for the basic operations 2
Examples - cont. or interpolation search 3
Abstract Data Type (ADT) Def. a collection of related data items together with an associated set of operations e. g. whole numbers (integers) and arithmetic operators for addition, subtraction, multiplication and division. e. g. Seats for TFA Basic operations: find empty seat, reserve a seat, cancel a seat assignment Why "abstract? " Data, operations, and relations are studied independent of implementation. What not how is the focus. 4
Implementation of an ADT Def. Consists of storage structures (aka data structures) to store the data items and algorithms for the basic operations. The storage structures/data structures used in implementations are provided in a language (primitive or built-in) or are built from the language constructs (user-defined). In either case, successful software design uses data abstraction: Separating the definition of a data type from its implementation. 5
istringstream ostringstream 6
Simple Data Types (§ 2. 2) Memory: 2 -state devices « bits 0 and 1 Organized into bytes (8 bits) and words (machine dependent — e. g. , 4 bytes). Each byte (or word) has an address making it possible to store and retrieve contents of any given memory location. Project 1 (See App. B re base 2, 8, 16) Therefore: the most basic form of data: sequences of bits simple data types (values are atomic — can't be subdivided) are ADTs. Implementations have: characters integers » Storage structures: memory locations reals logical » Algorithms: system hardware/software to do basic operations. 7
Boolean data Data values: {false, true} In C/C++: false = 0, true = 1 (or nonzero) Could store 1 value per bit, but usually use a byte (or word) Operations: and or not && || (See bit tables on p. 34) ! x !x 0 1 1 0 8
Character Data App. A Java 9
Integer Data Nonegative (unsigned) integer: type unsigned (and variations) in C++ Store its base-two representation in a fixed number w of bits (e. g. , w = 16 or w = 32) App. B 88 = 0000010110002 Signed integer: type int (and variations) in C++ Store in a fixed number w of bits using one of the following representations: 10
Sign-magnitude representation Save one bit (usually most significant) for sign (0 = +, 1 = – ) Use base-two representation in the other bits. 88 ® _00001011000 0 sign bit – 88 ® 1_00001011000 Cumbersome for arithmetic computations 11
Two's complement representation For nonnegative n: Use ordinary base-two representation with leading (sign) bit 0 For negative n (–n): (1) Find w-bit base-2 representation of n WHY? (2) Complement each bit. (3) Add 1 (Flip all bits from rightmost 0 to the end) Example: – 88 1. 88 as a 16 -bit base-two number 2. Complement this bit string 3. Add 1 Same as sign mag. WHY? 000001011000 111110100111 111110101000 12
Good for arithmetic computations (see p. 38) These work for both + and – integers 5 + 7: 111¬¾¾ carry bits 0000000101 +0000000111 0000001100 5 + – 6: 0000000101 +1111111010 11111111 13
Biased representation Add a constant bias to the number (typically, 2 w – 1) ; then find its base-two representation. Examples: 88 using w = 16 bits and bias of 215 = 32768 1. Add the bias to 88, giving 32856 2. Represent the result in base-two notation: 100001011000 Note: For n > 0, just change leftmost bit of binary representation of n to 1 – 88: 1. Add the bias to -88, giving 32680 2. Represent the result in base-two notation: 011110101000 ® Good for comparisons; so, it is commonly used for exponents in floating-point representation of reals. 14
Problems with Integer Representation Limited Capacity — a finite number of bits An operation can produce a value that requires more bits than maximum number allowed. This is called What's INT_MAX + 1? overflow. See climits (App. C) So none of these is a perfect representation of (mathematical) integers — can only store a finite (sub)range of them. 15
Real Data p. 756 2. Store: — sign of mantissa in leftmost bit (0 = +, 1 = – ) — biased binary rep. of exponent in next 8 bits (bias = 127) — bits b 2 b 3. . . in rightmost 23 bits. (Need not store b 1 — know it's 1) Example: 22. 625 = 10110. 1012 Floating point form: 1. 01101012 ´ 24 double: Exp: 11 bits, bias 1023 Mant: 52 bits (see p. 41) + 127 16
Problems with Real Representation What's 10*DBL_MAX? See cfloat (App. C) Roundoff error (pp. 41 -42) Most reals do not have terminating binary representations. Example: 0. 7 = (0. 10110011001100110. . . )2 p. 756 e. g. , 44. 7 Roundoff error may be compounded in a sequence of operations. Be careful in comparing reals with == and !=. 17
C-Style Data Structures: Arrays (§ 2. 3) Defn of an array as an ADT: An ordered set (sequence) with a fixed number of elements, all of the same type, where the basic operation is direct access to each element in the array so values can be retrieved from or stored in this element. Properties: • Ordered so there is a first element, a second one, etc. • Fixed number of elements — fixed capacity • Elements must be the same type (and size); use arrays only for homogeneous data sets. • Direct access: Access an element by giving its location — the time to access each element is the same for all elements, regardless of position. — in contrast to sequential access (where to access an element, one must first access all those that precede it. ) 18
Declaring arrays in C++ element_type array_name[CAPACITY]; where element_type array_name CAPACITY is any type is the name of the array — any valid identifier (a positive integer constant) is the number of elements in the array Can't input the capacity The compiler reserves a block of consecutive memory locations, enough to hold CAPACITY values of type element_type. The elements (or positions) of the array are indexed 0, 1, 2, . . . , CAPACITY - 1. e. g. , double score[100]; Better to use a named constant to specify the array capacity: const int CAPACITY = 100; double score[CAPACITY]; score[0] score[1] score[2] score[3]. . . Can use typedef with array declarations; e. g. , const int CAPACITY = 100; typedef double Scores. Array[CAPACITY]; score[99] Scores. Array score; . . . 19
How well does C/C++ implement an array ADT? As an ADT In C++ ordered indices numbered 0, 1, 2, . . . , CAPACITY - 1 fixed size CAPACITY specifies the capacity of the array same type elements element_type is the type of elements direct access subscript operator [] 20
Subscript operator [] is an actual operator and not simply a notation/punctuation as in some other languages. Its two operands are an array variable and an integer index (or subscript) and is written array_name[i] Here i is an integer expression with 0 < i < CAPACITY – 1. [] returns the address of the element in location i in array_name; so array_name[i]is a variable, called an indexed (or subscripted) variable, whose type is the specified element_type of the array. Also, it can have an index This means that it can be used on the left side of an assignment, in input statements, etc. to store a value in a specified location in the array. For example: // Zero out all the for (int i = 0; i < score[i] = 0. 0; // Read values into for (int i = 0; i < cin >> score[i]; elements of score CAPACITY; i++) the first num. Scores elements of score num. Scores; i++) // Display values stored in the first num. Scores elements for (int i = 0; i < num. Scores; i++) cout << score[i] << endl; 21
Array Initialization In C++, arrays can be initialized when they are declared. an array literal Numeric arrays: element_type num_array[CAPACITY] = {list_of_initial_values}; Example: double rate[5] = {0. 11, 0. 13, 0. 16, 0. 18, 0. 21}; Note 1: If fewer values supplied than array's capacity, remaining elements assigned 0. double rate[5] = {0. 11, 0. 13, 0. 16}; What’s an easy way to initialize an array to all zeros? Note 2: It is an error if more values are supplied than the declared size of the array. How this error is handled, however, will vary from one compiler to another. Note 3: If no values supplied, array elements are undefined (i. e. , garbage values). 22
Character arrays: Character arrays may be initialized in the same manner as numeric arrays. char vowel[5] = {'A', 'E', 'I', 'O', 'U'}; declares vowel to be an array of 5 characters and initializes it as follows: Note 1: If fewer values are supplied than the declared size of the array, the zeroes used to fill uninitialized elements are interpreted as the null character '