Data Structures Final 🧢‍⃠

Réussis tes devoirs et examens dès maintenant avec Quizwiz!

which version of increment "++" (pre or post) is generally more efficient*

pre (++p); post (p++) makes a copy each time it activates, even if the return value is never used

Suppose that I have the following declarations: int data[100]; size_t i; Write a small segment of C++ code that will shift data[51] ...data[99] down one spot to the location data[50] ...data[98]. The value of data[99] remains at its original value.

starting from the front of the sequence

In chapter 3, the CAPACITY of a bag is declared as a static member constant. In this context, what is the meaning of the word "static"?

static indicates that the entire class has only one copy of this member.

explain the advantage of template classes

when a class depends on an underlying data type, the class can be implemented as a template class, which gives the class the ability for several different versions of a class to be created from a single class, like a template function

as discussed in class and in the textbook, describe the three uses of stacks*

"Stacks are used to keep track of local variables when a program is run (how?). Stacks can be used to search a maze or a family tree or other types of branching structures. Another use is being able to undo commands in the proper order (e.g., for a word processor) or taking something apart then putting it back together in the right order (e.g., repairing piston rings on a car engine)."

The bag class has a member function with the prototype: void insert(const value_type& entry); Explain where the value_type is defined. Also, list two reasons why it is better to have such a definition (rather than just using an int).*

"The value_type is declared in the class definition (i.e., in the header file) as a typedef. This convention defines the value of the container in only one place making it easy to change later. Also, use of value_type documents the type of data that the container will hold."

suppose that a_ptr and b_ptr are node pointers. Write one clear sentence to explain when the expression (a_ptr==b_ptr) will be true

"the equality will be true when both pointers point to the same node object."

what is the value of the postfix expression 6 3 2 4 + - *?

( 6 * ( 3 - ( 2 + 4 ) ) ) ( 6 * ( 3 - 6 ) ) ( 6 * -3 ) -18

if DATA is a circular array of CAPACITY elements, and LAST is an index into that array, what is the formula for the index after LAST?

(LAST + 1) % CAPACITY

Consider the following statements: int *p; int i; int k; i = 42; k = i; p = &i; After these statements, list all the ways the value of i can be assigned the value of 75*

*p = 75; i = 75;

explain why an iterator using prefix notation (++iter) returns the iterator while an iterator using postfix notation (iter++) returns a copy

++iter increments the value BEFORE returning the value iter++ makes a copy of iter before it's incremented, even if the return value is never used

What is printed by the following statements? int i = 1; int k = 2; int *p1; int *p2; p1 = &i; p2 = &k; p1 = p2; *p1 = 3; *p2 = 4 std::cout << i;*

1

consider the following function: void super_write_vertical(int number) // postcondition: the digits of the number have been written, stacked vertically. If number is negative, then a negative sign appears on the top. { if (number < 0 ) { cout << '-' << endl; super_write_vertical(abs(number)); } else if (number < 10) { cout << number << endl; } else { super_write_vertical(number/10); cout << number % 10 << endl; } } what values of number are directly handled by the stopping case?

< 10 and >= 0

for the execution of recursive functions, the compiler and operating system store function invocation information. What data structure is used to store all the executions of the functions? Why is this data structure used? What is this data structure called in the context of programming languages?

A run-time stack it pushes the next activation record to the top of the run-time stack, useful because it uses LIFO instead of FIFO

Here is the INCORRECT pseudocode for the algorithm which is supposed to determine whether a sequence of parenthesis is balanced declare a character stack while (more input is available) { read a character if (the character is a '(' ) push it on the stack else if ( the character is a ')' and the stack is not empty ) pop a character off the stack else print "unbalanced" and exit } print "balanced" Which of these unbalanced sequences does the above code think is balanced? What fix should be made to the code? a. ( ( ( ) ) b. ( ) ) ( ( ) c. ( ( ) ( ) ) ) d. ( ( ) ) ) ( )

So according to this algorithm, letter A would be considered balanced despite it being unbalanced. This is because it pushes the first three '(' onto the stack, and they are popped off when the corresponding ')' is read, and it gets to the end and there is a stray '(' remaining on the stack. Since there is only an initial check for the stack being empty, it prints balanced which is incorrect.

Explain why the order of an algorithm is generally more important than the speed of the processor. Explain whether or not this is ALWAYS the case (e.g. for all possible inputs, explain whether or not a logarithmic algorithm to solve a problem MUST ALWAYS perform faster than a linear algorithm to solve the same problem).*

We are just generalizing when we say that O(log n) is more efficient. We can find cases where it is less efficient. EXAMPLE: You have a sorted list of 11 numbers. So we will need to decide if we need sequential sorting or binary sorting. Sequential is O(n) binary is O(log n) So if we are searching for the first number in our sorted list it would be best for us to use the sequential method because it checks for the number one-by-one and would immediately get the correct answer. Whereas binary would take about 4 tries to find the correct number.

Chapter 4 provides a bag class that stores the items in a dynamic array. Use an example with pictures to explain what goes wrong if the automatic assignment operator is used for this bag*

both pointers would point to the same dynamic array, so any change to x's array will also change y's array

give the traditional terms for adding and removing elements from a queue

enqueue- add dequeue- remove

in general, what are the two components of the body of a recursive function or method?

stopping case (case in which the entire computation is accomplished without recursion) and the recursive call

Suppose that you are storing a collection of items in a partially-filled array. You will declare the array and perhaps a constant to indicate the array's size. What else must you keep track of?

how much of the array is currently being used?

which stack operations, i.e push, pop, top, and is_empty, can result in a stack underflow? What are the conditions when this would happen?

if you use pop or top while is_empty is true

consider a queue implemented with a linked list, keeping track of a front pointer and a rear pointer. Which, if either, of these pointers will change during an insertion into a non-empty queue?

just rear

briefly describe what a doubly linked list is

like a simple linked list, except that each node contains two pointers, one pointing to the next node, and one pointing to the previous node

draw a complete binary tree with exactly six nodes. Put a different value in each node. Next, assume an array implementation for the binary tree ADT and draw an array with six components showing where each of the six node values would be placed in the array

1 / \ 2 3 / \ / 4 5 6 [1, 2, 3, 4, 5, 6]

Draw a full binary tree with at least 6 nodes

1 / \ 2 3 / \ / \ 4 5 6 7

When a class uses dynamic memory, list four general rules to follow regarding data members, member functions, automatic value semantics, and releasing dynamically allocated memory when the object is no longer needed.*

1. Some of the member variables of the class are pointers 2. Member functions allocate and release dynamic memory as needed 3. The automatic value semantics of the class is overridden (otherwise two different objects end up with pointers to the same dynamic memory) This means that the implementer must write an assignment operator and a copy constructor for the class 4. The class has a destructor. The primary purpose of the destructor is to return all dynamic memory to the heap.

list the four rules for classes that use dynamic memory

1. some of the member variables of the class are pointers 2. member functions allocate and release dynamic memory as needed 3. the automatic value semantics of the class is overridden 4. the class has a destructor

consider the following pseudocode: declare a stack of characters while ( there are more characters in the word to read ) { read a character push the character on the stack } while ( the stack is not empty ) { write the stack's top character to the screen pop a character off the stack } What is written to the screen for the input "ccaarrss"? For the input "racecar"? What is interesting about the output for "racecar"?

1. the input ccaarrss outputs ssrraacc 2. the input racecar outputs racecar 3. the input racecar is interesting because it is a palindrome.

what is the minimum number of nodes in a complete binary tree with depth 3

8 (?)

what is the minimum number of nodes in a full binary tree with depth 3

15

suppose that you are exploring a rectangular maze containing 15 rows and 12 columns. What is the maximum number of recursive calls that can be generated if you start at the entrance of the maze and call traverse_maze()?

15 x 12 is the upper bound

describe the state of the stack s (i.e. count of items and the order of items starting with the top of the stack) after executing the following lines of code: stack<int> s; s.push(1); s.push(2); s.push(3); s.pop( );

2 items in the stack, with an order of 2,1

consider this function declaration: void quiz(int i) { if (i > 1) { quiz(i/2); quiz(i/2); } cout << "*"; } how many asterisks are printed by the function call quiz(5)?*

7

Expand the acronym ADT and explain what it is.

Abstract Data Types referring to a class that is presented to other programmers with information hiding.

List one way the bag and sequence classes are similar. List one way they are different.*

Bags and sequences are both containers. They are also both flexible with item types Sequences hold their elements in order whereas bags do not.

suppose you have two iterators, s and t, over the same container and both *s and *t equal 42. Will (s == t) always be true? Why or why not?*

Both places have the same data, but the corresponding links are not the same; just because the data is the same, doesn't mean the links will be the same

what is a contract

Contract: As a programmer, the contract tells them precisely what the function does. It states that if one programmer makes sure that the precondition is met when the function is called, then the other programmer ensure that the function returns with the postcondition satisfied. ______ In english, the three parts of a contract are: 1. when is it appropriate to call a method (or function)? (precondition) 2. what is a method (or function) supposed to have done? (postcondition) 3. did a method (or function) execution screw up the state of whatever it was supposed to achieve? (class invariance)

what is the typical worst-case time for inserting an element into a dynamic array? Into a linked list?

Dynamic array: Linear (O(n)) Because to insert an element into an array, you must "shove" the elements to make room for the new element Linked list: constant because it is the same amount of time/steps no matter the size of the list

what technique is used to provide the capability to step through items of a container class? Explain the two types of this technique and a pro and con of these types*

Internal/External Iterators; internal iterator: Uses member functions to access items pro: simpler to manage con: set number of iterators (typically 1) external: pro: can have any number of iterators con: create separate classes and write methods (more complex)

describe the two differences between the semantics of stacks and queues*

LIFO (Stack)- one end to enter elements into FIFO(queue)- two ends to enter elements into

expand the acronym LIFO and explain what it means. How does this term relate to stacks?

Last In First Out This means that the last item that was just added into the stack is the first one to be "popped" or, removed, from the stack

below is a small binary tree 14 /\ 2 11 /\ /\ 1 3 10 30 / / 7 40 circle all the leaves. Put a square box around the root. Draw a star above each ancestor of the node that contains 10. Put a big X through every descendant of the node that contains 10.

Leaves: 1, 3, 7, 40 Root: 14 Ancestors of 10: 11, 14 Descendants of 10: 7

what is the usual worst-case performance for resizing a container class that stores its data in a dynamic array (using Big-Oh notation)?

Linear, O(n)

The public part of the throttle declaration from class notes is shown below. Mark each member function as follows: mark C for every constructor and mark X for every function that is forbidden from changing the throttle's data fields. class throttle { public: throttle( ); throttle(int size); void shut_off( ); void shift(int amount); double flow( ) const; throttle( ); throttle(int size); void shut_off( ); void shift(int amount); double flow( ) const; bool is_on( ) const; . . . bool is_on( ) const; . . .

Mark C: notice that it has the same name as the class throttle( ); throttle(int size); Mark X: Notice the const after double shift(int amount) const; bool is_on( ) const;

Using big-O notation, describe the worst-case time analysis for the following loop: 𝚠𝚑𝚒𝚕𝚎 (𝚗 > 0) { 𝚗 = 𝚗/𝟷0; // 𝚞𝚜𝚎 𝚒𝚗𝚝𝚎𝚐𝚎𝚛 𝚍𝚒𝚟𝚒𝚜𝚒𝚘𝚗 }*

O(n)

what is a post condition

Postcondition: a statement describing what will be true when a function call is completed. If the function is correct and the precondition was true when the function was called, then the function will complete, and the postcondition will be true when the function call is completed.

what is a precondition

Precondition: a statement giving the condition that is required to be true when a function is called. The function is not guaranteed to perform as it should unless the precondition is true.

As outlined in the book, describe one good method for precisely specifying WHAT a function must do, without indicating HOW the function accomplishes its work. Provide an example, using a small function.*

Preconditions and postconditions: they specify what the function must do without indicating how it accomplishes the work. This is also a form of information hiding. double celsius_to_fahrenheit(double c); //precondition: c is a Celsius temperature no less than absolute zero //postcondition: the return value is the temperature c converted to fahrenheit degrees.

Consider the implementation of the stack using a partially-filled array. What problem is encountered if we try to store the top of the stack at location [0] and the bottom of the stack at the last used position of the array?

Putting them at the bottom is more efficient because you don't have to constantly push elements to make more space like when you insert at the head

what property of a fractal lends itself to recursive thinking

Recursion is permitting a function implementation to contain a call to itself A fractal is a pattern that produces a picture, which contains an infinite amount of copies of itself.

what happens if you call new but the heap is out of memory? What is the default behavior?*

The default behavior is that it will print an error message and halt the program. It will also throw the bad_alloc error/exception

What are 3 good boundary values to test when removing an element from a sequence?*

The first value, last value, and current value (I think this is right, feel free to correct me if I am wrong D:)

consider the following prototype: function foo (const int * p); what restriction does the const keyword provide within the implementation of foo?

The function can't change the value of what p is pointing to

suppose we have a circular array implementation of the queue class, with ten items in the queue stored at data_[2] through data_[11]. The CAPACITY is 42. Where does the push member function place the new entry in the array?

The new elements are inserted at data[12]

How are constant member functions declared? How are constant member functions useful?*

They are declared by using the keyword const, this makes it forbidden from changing the object. double flow( ) const; This is useful because it informs the compiler and other programmers that the function cannot change the object.

For functions or methods that are inverse pairs (e.g., the operator== and operator!= member functions of a class), explain the proper approach for implementation.*

This is the inverse. as you can see the inverse of the == ( so the !=) calls == in order to check what the bool returned. If the bool returns true from == then once the != calls the == it will inverse the bool and it would then return false. This is using reuse. reuse is when one function reuses another functions information by calling the function.

Suppose m is an STL multiset. In what situations would m.begin( ) equal m.end( )?

When m contains no items

explain what it means that entries in a stack are ordered. What is the order?

When we say that the entries in a stack are ordered means that the entries can only be accessed from one end (i.e. top, then second, third, etc.) The order is Last In First Out (LIFO)

When should you use a const reference parameter?*

You should use the const reference parameter when you are looking for efficiency. With value parameters they will make a copy of the variables where as const reference parameters do not make a copy. Const reference parameters instead use the variable given and tell the compiler that it is not able to change it (hints the const). The best time to use this is when you have a large class (as a parameter). Pass in the object itself don't make a copy but also don't change the object. example const statistition& s1

briefly describe what a linked list is

a linked list is a sequence of items arranged one after another, with each item connected to the next by a link

explain the advantage of template functions

allows for several different versions of a function to be created, eliminating the need to create multiple functions when just one can be used

what is class invariance (or the invariant of the class)

always make an explicit statement of the rules that dictate how the member variables of a class are used. (all of the functions (except constructors) can count on the invariant being valid when the function is called. each function also has the responsibility of ensuring that the invariant is valid when the function finishes)

Write the first few lines of this function so that it uses the ASSERT facility to check its precondition: void exam(int i) //precondition: i is not equal to 42. . . .

assert(i != 42)

suppose that a new foo class has this prototype for an overloaded assignment operator: void operator =(const foo& source); In an assignment statement a = b, what will be the actual argument for the formal parameter source?

b

suppose that the variable cursor points to a node in a linked list (using the node definition with member functions called data( ) and link( )) What boolean expression will be true when cursor points to the tail node of the list? a. (cursor == NULL) b. (cursor->link( ) == NULL) c. (cursor->data( ) == NULL) d. (cursor->data( ) == 0.0) e. none of the above

b because the tail pointer always points to null

The following for-loop is intended to print 42 "ouch!"es, but it's not working as intended. Why? std::size_t i; for (i = 41, i >= 0; --i) { std::cout << "Ouch!" << std::endl; }

because its size_t (size_type) is unsigned which means that it cannot receive negative values, which means that it will never get to -1 like it was intended, and will be in an infinite loop.

why is it a bad idea to place USING directives in the implementation of a template class

because there can be conflicts with names in that namespace; could cause naming conflicts

at a minimum, what information does an activation record store?

contains info as to where the function should return after computation

consider the following code with ENQUEUES and DEQUEs const int CAPACITY =5; queue<int> q (CAPACITY); q.enqueue (2); q.enqueue (4); q.enqueue (6); q.enqueue (8); q.enqueue (10); q.dequeue ( ); q.dequeue ( ); q.enqueue (12); Suppose that q represented by a circular array. Draw the state of these private member variables of q after the above code has executed: first_: last_:*

data_[0]: 12 data_[1]: data[2]: 6 data[3]: 8 data[4]: 10 first_: data[2] last_: data[0]

which queue operations (enqueue/dequeue, and is_empty), can result in a queue underflow? What are the conditions when this would happen?

dequeue, when is_empty is true

consider this prototype for a template function: template <class Item> void foo(Item x); Which is the right way to call the foo function with an integer argument i?

foo<int>(i)

write a recursive function that has one parameter that is a non-negative integer. The function writes out that number of asterisks(*) to the screen, followed by that number of exclamation points (!) do not use any loops or local variables

func(int times) { if (n > 0) { cout << "*"; func(n-1); cout << "!"; } }

with the previous question in mind, how does one make it so you can change the int but you cannot point to anything else with the previous prototype foo

function foo (int* const p);

what is information hiding

information hiding is giving as much information as needed and if it is not pertinent to the user then it will not be shared. (the trick is to know only as much as you need, but no more.)

Describe the difference between an internal and external iterator.

internal- is a part of the class member function and there is only one external- is its own class and you can have multiple (why??). it is also very flexible

consider an implementation of a queue with a circular array, keeping track of first, last, and count (the number of items in the array). Suppose first is zero, and last is CAPACITY-1. What can be deduced about count?

it could be 0 or full (at capacity); it could be empty or full

considering the write_vertical and super_write_vertical discussed in the textbook, what is another way the super_write_vertical function could use recursion but not by calling itself?

it could call write_vertical in the function instead of super_write_vertical

what is the typical worst-case time for inserting an element into a linked list?

it is constant because it is the same for all, no matter the size (why?)

what is the typical worst-case time for inserting an element into a dynamic array?*

it is linear (O(n)) because with once you insert an element into an array, you must "shove" the values to make space for the new element

suppose that p is a pointer to a node in a linked list, and *p is not the tail node. What are the steps to removing the node after *p? Use one short English sentence for each step

node* remove_ptr = previous_ptr->link( ); // ☝️ sets the pointer to the node we want to delete previous_ptr->set_link(remove_ptr->link( )); // ☝️ resets the link field of previous_ptr so that it points to the node we want to delete delete remove_ptr; // ☝️ frees up remove_ptr to the heap thereby freeing up memory

why does the node class have two versions of the link member function

one is: node* link( ) { return link_field; } ☝️ is a non-constant member function because it provides better accuracy about how the function's results might be used and the other is: const node* link( ) const { return link_field; } ☝️ this is declared as a constant member function so that it cannot later be used to change any part in the linked list

Suppose that I have the following declarations int data[70]; size_t i; write a small segment of C++ code that will shift data[20] ...data[68] up one spot to the locations data[21] ...data[69]. Then insert the number 27 at location data[20].*

opening up a hole come from the other end (the back of the sequence) ( ͡° ͜ʖ ͡°)

in the singly linked list implementation of the queue class having the front_ptr_ and rear_ptr_ data members, where does the PUSH member function place the new entry in the linked list? Why?

places it at the rear of the queue, because it is easy to be inserted at the rear but to remove something at the rear requires for the whole list to be traversed to assign rear_ptr to the next value

describe how to multiply 5 and 3 and then add 7 in prefix, infix, and postfix notation. What makes postfix evaluation "easy"?

prefix- + * 5 3 7 postfix- 5 3 * 7 + infix- (5 * 3) + 7 "Postfix notation is handy because it does not require parentheses and because it is particularly easy to evaluate (once you learn to use the notation). In fact, postfix notation often is used internally for computers because of the ease of expression evaluation."

what is a pro/con for linked lists

pro: better at insertions/deletions at a cursor con: effective insertions/deletions require maintaining both a cursor and a precursor if class operations take place at a cursor, then a linked list is better than a dynamic array

what is a pro/con for dynamic arrays*

pro: better at random access con: because of the random access, dynamic arrays cannot use cursors efficiently (compared to a linked list) if a class makes significant use of random access operations, then a dynamic array is better than a linked list

what is a pro/con for doubly linked lists

pro: better for a two-way cursor (for more effective insertions/deletions) con: "there's more management/code needed to support these lists, and there is more added space that is needed" if a class operations take place at a two-way cursor, then a doubly linked list is the best implementation

give the traditional terms for adding and removing elements from a stack

push- adding items to the stack pop- removing items from the stack

in the linked list implementation of the stack class, where does the push member function place the new entry on the linked list? Why?

takes place at the head because it is more efficient than traversing the entire list and inserting at the tail pointer

Consider the usual algorithm for determining whether a sequence of parentheses is balanced (i.e. using a stack to push and pop parenthesis). What is the maximum number of parenthesis that will appear on the stack at any one time when the algorithm analyzes the following input string: ( ( ) ( ( ) ) ( ( ) ) ) ?

the maximum number of parenthesis is 3 because according to the diagram, when it gets to 5 and 9 there are a total of 3

provide a definition for the phrase EXHAUSTIVE SEARCH WITH BACKTRACKING*

the term EXHAUSTIVE SEARCH means that all possibilities are tried. Backtracking is the process of a recursive call returning without finding the goal. When such a recursive call returns, we are back where we started, and we can explore other directions with further recursive calls.

you have computed the set union of two sets with sizes of 10 and 40 but the answer only has 42 items. How can this be?

the two sets had 8 items in common

when a template class is implemented the entire implementation file is included in the header file. Why is this needed?

to make the compiler's job possible; needs to have/know the template implementation code so it can get the ACTUAL implementation code

Explain why writing easily modifiable code is important.*

using all of the coding conventions (documentation, pre/post conditions) is important because of readability and efficiency for whoever needs to read your code. For example, if your code has clear pre/post conditions, the other programmer doesn't have to take the time to test values in your functions. And, the code will typically need to be modified.

as mentioned in the chapter, name the STL container classes that use dynamic arrays and doubly linked lists

vectors use dynamic arrays lists used doubly linked lists

Suppose that f is a function with a prototype like this: void f(_____________ head_ptr); // Precondition: head_ptr is a head pointer for a linked list // Post condition: the function f has done some computation with the // linked list, but the list itself is unchanged. What is the best data type for head_ptr in this function*

void f(node* head_ptr); It is using the * because in the post condition it mentioned that the list itself was unchanged

Suppose that f is a function with a prototype like this: void f(____________ head_ptr); // Precondition: head_ptr is a head pointer for a linked list // Post condition: the function f has done some manipulation of the // linked list, and the list might now have a new head node. What is the best data type for head_ptr in this function?

void f(node*& head_ptr); It is using *& because in the post condition it mentioned that it has done some manipulation of the linked list

suppose that p is a pointer variable that contains the NULL pointer. What happens if your program tries to read or write *p? If anything happens does it happen at compile-time or runtime?

what happens when you try to dereference a NULL pointer (*p) is that the program essentially tries to pull something out of nothing. This error is not thrown at compile-time, but whenever the pointer is used in the program during run-time, as a core dump or address protection violation

does the compiler generate and compile the implementation of a template function or class when it encounters the implementation or when the implementation is instantiated (when the implementation is invoked) in the code? Why is this?

when implementation is invoked because data types must be filled in to generate code

explain why a head pointer is needed for a linked list (whereas dynamic arrays didn't need a head pointer)

when we are building/manipulating a linked list, the list is accessed through one or more pointers to the nodes. The most common ways to access the nodes is through the head pointer (or tail pointer)

consider the implementation of the queue using a circular array. what problem arises if we try to keep all the items at the front of a partially-filled array (so data_[0] is always the front)

whenever the first item is removed, all other items must shift so the next item is at data[0]


Ensembles d'études connexes

Module 21 NCLEX style questions Pressure Ulcers

View Set

Human Physiology: Chapter 9 (Autonomic Nervous System)

View Set

PHARM - Renal and Urinary Medications

View Set

EMT: Chapter 24 [trauma overview]

View Set

Case Problem Analysis 08.1: Trade Secrets

View Set