cs 32 final notes

Upload: sachlyric

Post on 03-Jun-2018

224 views

Category:

Documents


1 download

TRANSCRIPT

  • 8/12/2019 Cs 32 Final Notes

    1/21

    #include cin.ignore(10000, '\n'); // ignores up to char or 10000 chars, used after cin >> intendl; // '\n'cout.setf(ios::fixed); // fixed vs. scientific (ios is not a namespace)cout.precision(2); // 2 decimal// This header defines istream and ostream

    #include string s = "literal";string u; // default empty stringu = s; // assignment (creates a copy)(s == u) // comparison, can use > and > s; // read up to whitespace w/o using, store w/o whitespaces.size(); // lengths.length(); // same as aboves[i]; // return char, valid range 0 to size - 1s += u; // appends.substr(index, length) // returns string starting (inclusive) at index with specified length,

    // length is optionalEscape sequence: \Important special chars: \n \t \\

    \' \" \0

    #include // Not in the std namespace char s[10] = "Hi"; // length 2, index 2 reserved for \0, need not fill entire arraychar u[] = "Compiler makes this string just long enough.";strlen(s);strcpy(dest, source); // assignmentstrncpy(dest, source, limitToCopy);strcmp(a, b); // 0 if equal, pos if a > b (a is lexicographcally after b), neg if a < bsrrncmp(a, b, limitToCheck);strcat(dest, source); // concatenatestrncat(dest, source, limitToCopy);cout x++it // also it++--it // also it--

  • 8/12/2019 Cs 32 Final Notes

    2/21

    #include stack mystack;mystack.top()mystack.push() // pushes to top of stackmystack.emplace(1) // constructs T with args and pushes to top of stackmystack.pop() // pops off top, returns void

    #include queue myqueue;myqueue.push() // pushes to back of queuemyqueue.back()myqueue.front() // next element to be poppedmyqueue.pop()myqueue.emplace(1) // see stack

    #include // Any insertion/deletion invalidates iteratorvector myvector;myvector[0] // same as myvector.at(0)myvector.front() // same as myvector[0]myvector.back() // same as myvector[myvector.size() - 1]myvector.push_back(0)myvector.pop_back() // returns void

    #include // Only erasing the item at iterator can invalidate an iteratorlist mylist;mylist.front()mylist.back()mylist.push_front(0)mylist.pop_front() // returns voidmylist.push_back(0)mylist.pop_back() // returns voidmylist.insert(it, 0) // inserts before the element at it; in other words, now 0 is at it

    #include // DOES NOT HAVE REVERSE ITERATORS// Only erasing the item at iterator can invalidate an iteratorunordered_set myuset;myuset.insert(0)myuset.find(0)myuset.bucket_count()muuset.load_factor() // returns float, equal to size / bucket_count

    #include // DOES NOT HAVE REVERSE ITERATORS// Only erasing the item at iterator can invalidate an iteratorundordered_map myumap;myumap["weed"] // returns int&, myumap.at("weed") will throw out_of_range if key DNEmyumap.insert("weed", 0)myumap.load_factor() // returns float, equal to size / bucket_countmyumap.bucket_count()

    #include // Only erasing the item at iterator can invalidate an iteratorset myset;myset.insert(0)myset.find(0) // returns iterator (it == myset.end() if not found)myset.lower_bound(0) // returns iterator either equal or greater thanmyset.upper_bound(0) // returns iterator less thanmultiset mymset; // can have duplicate values, same functions as above but also:mymset.equal_range(0) // returns pair, actually set has this too

  • 8/12/2019 Cs 32 Final Notes

    3/21

    #include // Only erasing the item an iterator can invalidate an iteratormap mymap;mymap["weed"] // returns int&, mymap.at("weed") will throw out_of_range if key DNEmymap.insert(std::pair("weed", 0))mymap.find("weed") // returns iteratormymap.lower_bound("weed") // returns iterator either equal or greater thanmymap.upper_bound("weed") // returns iterator less thanmultimap mymmap; // can have duplicate values, same functions as above but also:mymmap.equal_range("weed") // returns pair, actually map has this too

    #include // Pointers on arrays work as iterators toofind(it_first, it_last, 0) // [first, last)find_if(it_first, it_last, func) // bool func(int oneArg)sort(it_first, it_last, func) // vectors/arrays only, bool func(int arg1, int arg2), true if arg1 wrapper(); // calls Foobar's version of virtualFunc

    }

    class Animal{

    public:Animal(int a) { ... }; // must be constructed with arg

    }

  • 8/12/2019 Cs 32 Final Notes

    5/21

    class Dog : public Animal{

    public:Dog() : Animal(10) { ... } // use initializer list to deal with thisDog(int a) : Animal(a) { ... }bool operator

  • 8/12/2019 Cs 32 Final Notes

    6/21

    d++; // pointer arithmetic, points to next integerObject * obj = new Object(); // new returns a pointer type, parentheses optional if default

    // constructing (unless you want to get into ugly initialization// technicalities)

    obj->function();obj->m_data; // shorthand for access from pointer*(c + 1) = 1; // equivalent to c[1]

    // recall that pointer arithmatic is differentthis; // in a class member function call, returns pointer to the object

    // that is running the functiondelete b; // does nothing if b == nullptrdelete [] d;

    Complex declarationsint *p[10]; // array of pointers to an intint (*p)[10]; // pointer to array of an intint **p; // pointer to a pointer to an intvoid foo(int* &var); // reference to a pointer of intint& *var and int& &var are illegalconst int *p; // pointer to a constant intint const *p; // pointer to a constant intint * const p; // constant pointer to an int (you can change the value of *p)

    Templatestemplate // put template on both class and function definintionclass Foo{public:

    swap(T& x, T& y);T m_t;struct bar { };

    }

    templatevoid Foo::swap(T& x, T& y){ } // template data type must be used in the formal parameter list

    templatevoid swap(T& x, B& y){ }

    templateinline T Foo::bar(T a) { } // template inline function

    templatetypename Foo::bar Foo::returnBar() { } // template, returning template

    // dependent struct

    Entire template function must be in a header file

    Stacks and queuesStacks can be implemented with an array and a counter that keeps track of the top element.Queues can be implemented with a linked list that has both a head and a tail pointer.You can also use a circular queue implemented with arrays; keep track of the head index, tailindex, and the count of objects in your queue.Declaring local variables, passing arguments to functions, and function returns are all placed on astack. Undoing things in word processors is also done on the stack.Queues can be used for holding data gotten from the internet.Both stacks and queues can be used for solving mazes.Stacks are LIFO (Last-in First-out), queues are FIFO (First-in First-out)

    Polymorphism Always use virtual on both the base and derived functions if they are to be redefined.(It technically does not matter for the derived function, but it's better if it does.)Always use virtual on destructors.No virtual constructors; you always know the class at time of construction, and they are class-local anyway.

    If you forget to make a destructor virtual, the subclass destructor will not be called if thecompiler knows only that the object is of the superclass.If the compiler knows that the object is of the subclass, then both destructors will be called.

  • 8/12/2019 Cs 32 Final Notes

    7/21

    The default copy constructor and assignment operator will work fine, but if your derived classneeds special functionality, it must define its own copy constructors and assignment operators(these should not be virtual):

    1.) For the copy constructor, you should instantiate the base class using the initializer list andpassing in your argument to the base class's (ie. Sub(const Sub& other) : Super(other))2.) For the assignment operator, you should explicitly call Super::operator=(other).

    If you allow these functions to be implicitly defined, they will automatically call the baseclass's version for you. In this sense, they are not technically "inherited."

    vtable is the table of pointers to virtual functions.

    RecursionEvery recursive function must have a base case that solves trivial problems without recursion.Every recursive function must have a simplifying step that converges towards the base case.Recursive functions must not use global, static, or member variables, only local and parameters.

    When using recursion on linked lists, you will probably be passing in nodes as parameters.You probably won't need a size parameter; just check the next node to see if it's the end of thelist or not.

    Two general categories of recursion:1.) Split into halves2.) Remove one element and try again

    You can write a helper function to make a simpler interface for others to use.

    Minimax (chess): give it a set depth of moves to test, and while depth isn't 0, try every move andcall again; when depth is 0, evaluate the board and find the best move.

    Linked Lists A series of nodes, where one node can point to the next node (singly-linked) or tothe previous node (doubly-linked). You will need at least the head or tail pointer, though havingboth is convenient.

    A dummy node goes at the head position and its next pointer is the first node, and its prev pointeris the last node. This means that there are no special cases to deal with. That is, there will beno null pointers to follow if the integrity of the list is maintained.

    When deleting from a singly-linked list, you will have to declare a temporary variable to rememberwhat node to delete when you are done.Be very careful with the order of your operations in linked lists.Always validate the pointer first.

    Singly-linked list, adding to the top: no special casesadding to the bottom: case 1: list is empty; case 2: list is not emptyadding to arbitrary location: case 1: list is empty; case 2: you're adding to

    the top; case 3: normal caseSingly-linked list, deleting: case 1: deleting first node; case 2: deleting any other node

    Binary Trees Trees in general may have any number of children, but binary trees only have at most two childrenEvery tree has a root nodeEvery node must have exactly one parent (except the root)Sibling nodes = nodes with same parentAncestor node = lies between current node and rootSubtree = any node and the collection of its subnodesnode depth = "level" of a tree, root has depth 0pruning = removing a section of the treegrafting = adding a section to the treetraversing = iterating though items in a treePre-order: current, left, rightIn-order: left, current, rightPost-order: left, right, currentLevel-order: use a queue

  • 8/12/2019 Cs 32 Final Notes

    8/21

    You can use binary trees to represent arithmetic expressions:each leaf node is an operandall others are operators

    Binary search trees: left sub-tree must be < node, right sub-tree must be > node

    Deletion in BST:use a cur pointer and a parent pointercase 1: node is a leaf (trivial)case 2: node has one child

    -determine which side of the parent's tree the node is on-rewire that side to the child

    case 3: node has two children-replace with the largest left descendant or smallest right descendant-make sure to apply case 1 or 2 to that descendant when moving it around

    case x: remember to delete the root pointer too if applicable

    Huffman encoding uses a binary tree:-compute frequency of byte patterns-find two lowest frequency patterns, and link them as children of a parent node

    -set parent node's frequency to sum of these two-replace these two patterns with the parent's node-repeat process until you have a binary tree-use the path taken to reach a leaf (ie. byte pattern) as the encryption scheme

    -ie. 0 means go left, 1 means to right-when decrypting, when you reach a leaf you know the encrypted character is finished-of course there is overhead in adding the encryption scheme to the data file

    Perfectly balanced trees have a max height of log_2(n)Heights of subtrees differ by at most 1Self-balancing trees include AVL, 2-3 and red-black trees

    AVL trees: each node has a balance value-1 if left is higher than right (larger than right), 0 if balanced, 1 if lower than right-must update balance values from new node to rootinsertion cases (after insertion and updating balances):case 1: all balances are -1 to 1 (trivial)case 2: if not, then rotate nodes

    -may require double rotation if multiple nodes do not have the right balance values

    Hash tablescollision = two or more values attempt to occupy the same bucketlinear probing = on collision, traverse down until you reach an empty bucket

    -results in a closed hash table with fixed capacity-to look up, use hashing function to find bucket, then traverse until you find exact value-deletion is troublesome--just assume you can't delete anything

    open hash table = each bucket contains a linked list-better for repeated insertion and deletion-still good performance even if you use all your buckets

    load = number of expected values / number of bucketsclosed w/ linear probing: insertion/finding: average # of tries = 1/2 * (1 + 1 / (1 - L))open: insertion/finding: average # of tries = 1 + L / 2

    -open is always more efficient than closedtry to use a prime number for bucket number, reduces number of collissions

    Hash functions must:1.) be deterministic2.) should have even distribution3.) should always be tested for how well it disperses itemssample hash functions: CRC32, CRC64, MD5, SHA2

    Binary trees vs hash tablesSpeed: Hash table = O(1), binary trees = O(log_2(n))Simplicity: Hash table = easy, binary trees = harderMax size: closed hash = limited, open hash = impacted by high load, binary tree = unlimitedSpace efficiency: hash = can waste a lot of space, binary tree = only uses as much as neededordering: hash = random, binary tree = ordered

  • 8/12/2019 Cs 32 Final Notes

    9/21

    Tables record = a group of related datafield = one element of a recordkey field = unique value across all recordsfor efficient searching, set up indexed trees to search through

    -store only the index of the record, not the record itself to avoid duplicate data-remember that if you ever update the record, you will need to update the trees-you can actually use any efficient structure, not just a tree

    Priority Queues/Heapspriority queue = every inserted element has a priority rating

    -dequeue by highest prioritypriority queues are efficiently implemented with heapsheaps are implemented using complete binary trees (top N-1 levels are all filled, bottom-most levelis filled from the left)Maxheap (max value on top): each node has a value greater than or equal to its childrenMinheap (min value on top): each node has a value less than or equal to its childrenExtracting top items: get the top value, overwrite it with the right-most node in the bottom level,delete that node, and repeatedly swap that node until it satisfies the max or min condition

    -the swapping part is called sifting downInserting an item: place node with value into the left-most unoccupied node on the bottom level,and swap upwards until it satisfies the max or min condition

    -the swapping part is called reheapificationimplemented with arrays:root value is heap[0], bottom-most, right-most node is heap[count - 1], bottom-most, left-mostempty spot is heap[count]left child index = 2 * parent index + 1right child index = 2 * parent index + 2parent index = (child index - 1) / 2To heapify an array, traverse backwards, considering each node to be the root of its own subtree,and sift down

    -start at node N/2 - 1; this indicates the first node with at least 2 nodes-this eliminates half of the trees you need to inspect

    Graphsstores a set of entities and keeps track of their relationshipshas vertices/nodes, and edges/arcs (connects two vertices)directed graph: an edge has a specific directionundirected graph: an edge is bi-directionalrepresented with a 2-d array, whose size in both dimensions is the number of vertices (adjacencymatrix)

    each element g[i][j] represents whether an edge exists between i and jforms an adjacency matrixfor an undirected graph, g[i][j] == g[j][i]

    multiplying a matrix by itself gives a resultant matrix that shows which vertices are two edgesapart, and doing so again gives you a matrix with vertices three edges apart, and so onrepresented with an array of linked lists (adjacency list)

    each list g[n] represents all the edges from vertex ndense graph = many edges, sparse graph = few edgesgenerally, use a matrix on dense graphs, use a list on sparse graphsdepth-first traversal via recursion/stacksbreadth-first traversal via queuesweighted edges = edge has a value associated with itweight of a path = sum of the weights of the edges between two vertices

    shortest path = particular path with lowest weight

    Designing OOPsIdentify objectsIdentify operations of objectsAssociate operations with classesDetermine relationships and data

    Class X uses Class YClass X has-a Class YClass X is-a Class Y

    Determine interactions

    Undefined behavioruninitialized primitive typesout of bounds accessreturn statement never reachedvariable array length for static array declaration (illegal on many compilers)

  • 8/12/2019 Cs 32 Final Notes

    10/21

    Common mistakes forgetting to use cin.ignore(10000, '\n'); after inputting a numbermismatched if and else statementsboundary conditionsforgetting break in a case statementforgetting the semi-colon after do-while, struct, class, or function declarationmisuse of & or const in function headersaccessing a variable out of scopeusing cin on an improper type (arrays, pointers)forgetting to dereference with either * or []not using == in comparisonsusing the wrong >> or

  • 8/12/2019 Cs 32 Final Notes

    11/21

    Operator precedence :: (scope resolution operator)

    . -> [] () ++ (postfix) -- (postfix)

    ++ (prefix) -- (prefix) ! - (unary) + (unary) *& new delete delete [] sizeof () (typecast)

    * / %

    + -

    >

    < > =

    == !=

    &&

    ||

    = += -= *= /= %=

    ? :

    throw

    ,

    ALGORITHM CHEAT SHEET

    set/map insertion: O(log n)finding: O(log n)deleting: O(log n)

    queue/stack insertion: O(1)popping: O(1)peeking: O(1)

    vectorinsertion (arbitrary): O(n)insertion (bottom): O(1)deletion (arbitrary): O(n)deletion (bottom): O(1)accessing (arbitrary): O(1)finding (arbitrary): O(n)

    list insertion (arbitrary): O(1)deletion (arbitrary): O(1)accessing (top or bottom): O(1)accessing (arbitrary): O(n)finding (arbitrary): O(n)

    heapInsertion: O(log n)Extraction: O(log n)Buliding: O(n) // counter-intuitive, but the fact that as you go up in levels, while the number of

    // swaps you may have to make increases, the number of nodes themselves decreases// causes it to converge in O(n) time

    Searches Linear search: O(n)Binary search: O(log n)

  • 8/12/2019 Cs 32 Final Notes

    12/21

    Sorts Insertion sort: O(n) for nearly sorted, otherwise O(n^2), can be used on linked lists, stableSelection sort: O(n^2) always, can be used on linked lists, minimizes item swaps, stableBubble sort: O(n) for nearly sorted, otherwise O(n^2), can be used on linked list, stable

    Shell sort: O(n^1.25), can be used on linked lists, fixed RAM usage, unstable

    Merge sort: O(n log n) always, can be used on linked lists, can be parallelized, requires n extramemory usage for merging, stableQuick sort: O(n log n), O(n^2) on nearly sorted (or in reverse) arrays or arrays w/ repeatedvalues, can be used on linked lists, can be parallelized, may require O(n) memory for recursion inworst case, unstableHeap sort: O(n log n) always, 1ow memory requirements, unstable

    SAMPLE CODE

    infix to postfix

    Initialize postfix to emptyInitialize the operator stack to emptyFor each character ch in the infix string

    Switch (ch)case operand:

    append ch to end of postfixbreak

    case '(':push ch onto the operator stackbreak

    case ')':// pop stack until matching '('

    While stack top is not '('append the stack top to postfixpop the stack

    pop the stack // remove the '('break

    case operator:While the stack is not empty and the stack top is not '('

    and precedence(ch)

  • 8/12/2019 Cs 32 Final Notes

    13/21

    bool isDigitOrCloseParen(char ch){

    return isdigit(ch) || ch == ')';}

    int precedence(char ch)// Precondition: ch is in "|&!("

    {static const string ops = "|&!(";static const int prec[4] = { 1, 2, 3, 0 };size_t pos = ops.find(ch);assert(pos != string::npos); // must be found!return prec[pos];

    }

    const int RET_OK_EVALUATION = 0;const int RET_INVALID_EXPRESSION = 1;

    int evaluate(string infix, const bool values[], string& postfix, bool& result)// Evaluates a boolean expression// If infix is a syntactically valid infix boolean expression, then postfix// is set to the postfix form of that expression, result is set to the value// of the expression (where in that expression, each digit k represents// element k of the values array), and the function returns zero. If infix// is not a syntactically valid expression, the function returns 1. (In// that case, postfix may or may not be changed, but result must be// unchanged.)

    {// First convert infix to postfix

    postfix = "";stack operatorStack;char prevch = '|'; // pretend the previous character was an operator

    for (size_t k = 0; k < infix.size(); k++){

    char ch = infix[k];switch(ch){

    case ' ':continue; // do not set prevch to this char

    case '(':case '!':

    if (isDigitOrCloseParen(prevch))return RET_INVALID_EXPRESSION;

    operatorStack.push(ch);break;

    case ')':if ( ! isDigitOrCloseParen(prevch))

    return RET_INVALID_EXPRESSION;for (;;){

    if (operatorStack.empty())return RET_INVALID_EXPRESSION; // too many ')'

    char c = operatorStack.top();operatorStack.pop();if (c == '(')

    break;postfix += c;

    }break;

    case '|':case '&':

    if ( ! isDigitOrCloseParen(prevch))return RET_INVALID_EXPRESSION;

    while ( ! operatorStack.empty() &&precedence(ch)

  • 8/12/2019 Cs 32 Final Notes

    14/21

    operatorStack.pop();}operatorStack.push(ch);break;

    default: // had better be a digitif (!isdigit(ch))

    return RET_INVALID_EXPRESSION;if (isDigitOrCloseParen(prevch))

    return RET_INVALID_EXPRESSION;postfix += ch;break;

    }prevch = ch;

    }

    // end of expression; pop remaining operators

    if ( ! isDigitOrCloseParen(prevch))return RET_INVALID_EXPRESSION;

    while ( ! operatorStack.empty()){

    char c = operatorStack.top();operatorStack.pop();if (c == '(')

    return RET_INVALID_EXPRESSION; // too many '('postfix += c;

    }if (postfix.empty())

    return RET_INVALID_EXPRESSION; // empty expression

    // postfix now contains the converted expression// Now evaluate the postfix expression

    stack operandStack;for (size_t k = 0; k < postfix.size(); k++){

    char ch = postfix[k];if (isdigit(ch))

    operandStack.push(values[ch-'0']);else{

    bool opd2 = operandStack.top();operandStack.pop();if (ch == '!')

    operandStack.push(!opd2);else{ bool opd1 = operandStack.top();

    operandStack.pop();if (ch == '&')

    operandStack.push(opd1 && opd2);else if (ch == '|')

    operandStack.push(opd1 || opd2);else // Impossible!

    return RET_INVALID_EXPRESSION; // pretend it's an invalid expression}

    }}if (operandStack.size() != 1) // Impossible!

    return RET_INVALID_EXPRESSION; // pretend it's an invalid expressionresult = operandStack.top();

    return RET_OK_EVALUATION;}

    recursive algorithms

    // Return true if any of the array elements is negative, false// otherwise.

    bool anyNegative(const double a[], int n){

    if (n

  • 8/12/2019 Cs 32 Final Notes

    15/21

    return false;if (a[0] < 0)

    return true;return anyNegative(a+1, n-1);

    }

    // Return the number of negative elements in the array.int countNegatives(const double a[], int n){

    if (n

  • 8/12/2019 Cs 32 Final Notes

    16/21

    return includes(a1+1, n1-1, a2, n2); // rest of a1, all of a2}

    bool pathExists(string maze[], int nRows, int nCols, int sr, int sc, int er, int ec){

    if (sr == er && sc == ec)return true;

    maze[sr][sc] = '@'; // anything non-'.' will do

    if (maze[sr-1][sc] == '.' && pathExists(maze, nRows, nCols, sr-1, sc, er, ec))return true;

    if (maze[sr+1][sc] == '.' && pathExists(maze, nRows, nCols, sr+1, sc, er, ec))return true;

    if (maze[sr][sc-1] == '.' && pathExists(maze, nRows, nCols, sr, sc-1, er, ec))return true;

    if (maze[sr][sc+1] == '.' && pathExists(maze, nRows, nCols, sr, sc+1, er, ec))return true;

    return false;}

    // Return the number of ways that all n2 elements of a2 appear// in the n1 element array a1 in the same order (though not// necessarily consecutively). The empty sequence appears in a// sequence of length n1 in 1 way, even if n1 is 0.// For example, if a1 is the 7 element array// 10 50 40 20 50 40 30// then for this value of a2 the function must return// 10 20 40 1// 10 40 30 2// 20 10 40 0// 50 40 30 3

    int countIncludes(const double a1[], int n1, const double a2[], int n2){

    if (n2 splitter come before all the other elements,// and all the elements whose value is < splitter come after all// the other elements. Upon return, firstNotGreater is set to the// index of the first element in the rearranged array that is//

  • 8/12/2019 Cs 32 Final Notes

    17/21

    if (n < 0)n = 0;

    // It will always be the case that just before evaluating the loop// condition:// firstNotGreater splitter){

    exchange(a[firstNotGreater], a[firstUnknown]);firstNotGreater++;

    }firstUnknown++;

    }}

    }

    // Rearrange the elements of the array so that// a[0] >= a[1] >= a[2] >= ... >= a[n-2] >= a[n-1]// If n next;

    // Check if ptr is last nodeif (ptr != nullptr && ptr->next == nullptr)

    return true;

    // Get next node's dataif (ptr != nullptr && ptr->next != nullptr)

    return ptr->next->value;

    // Get head node's dataif (m_head != nullptr)

    returb m_head->value;

  • 8/12/2019 Cs 32 Final Notes

    18/21

    // Check if list is emptyreturn m_head == nullptr;

    Linked list with dummy node operations // Initializem_head = new Node;m_head->m_next = m_head;m_head->m_prev = m_head;

    // Delete every nodeNode *p = m_head->m_prevwhile (m_size >= 0){

    Node *toDelete = p;p = p->m_prev;delete toDelete;

    }

    // Delete arbitrary nodep->m_prev->m_next = p->m_next;p->m_next->m_prev = p->m_prev;delete p;m_size--;

    // Search listNode *p;for (p = m_head->m_next; p != m_head && p->m_key != key; p = p->m_next)

    ;return p; // Returning m_head means not found

    // Insertion (to tail of list, but technically arbitrary)p->m_prev = m_head->m_prev;p->m_prev->m_next = p;p->m_next = m_head;m_head->m_prev = p;m_size++;

    Binary search tree operations// Left rotation, flip sides for right rotationNode *p = m_root->m_right;m_root->m_right = p->m_left;p->m_left = m_root;m_root = p;

    // Deletion// Let us assume curNode already points to the to be deleted node, and parent is its parentif (curNode->m_left == nullptr && curNode->m_right == nullptr){

    if (curNode == parent->m_left)parent->m_left = nullptr;

    elseparent->m_right = nullptr;

    delete curNode;}else if (curNode->m_left == nullptr) // grandchild on right node{

    if (curNode == parent->m_left)parent->m_left = curNode->m_right;

    elseparent->m_right = curNode->m_right;

    delete curNode;}else if (curNode->m_right == nullptr) // grandchild on left node{

    if (curNode == parent->m_left)parent->m_left = curNode->m_left;

    elseparent->m_right = curNode->m_left;

    delete curNode;}

  • 8/12/2019 Cs 32 Final Notes

    19/21

    else // we arbitrarily choose the largest node in the left subtree, over the smallest node in the{ // right subtree

    Node *replacement = curNode->m_left;while (replacement->m_right != nullptr)

    replacement = replacement->m_right;curNode->m_val = replacement->m_val; // and any other copying that must happendeleteNode(replacement); // alternatively, replacement is guaranteed to have either no

    // children or a left child, so you can manually code that in}

    Sorts and searches Selection sortfor (int i = 0; i < n; i++){

    // Find the smallest valueint min = i;for (int j = i + 1; j < n; j++)

    if (a[j] < a[min])min = j;

    // Swap smallest value with iswap(a[i], a[min]);

    }

    Insertion sort for (int i = 1; i < n; i++){

    // Move ith element as far down as possiblefor (int j = i; j > 0; j--){

    if (a[j] >= a[j - 1])break;

    swap(a[j], a[j - 1]);

    }}

    Bubble sortbool swapped;do{

    swapped = false;// At the end of the for loop, the max value will be at the top of the arrayfor (int i = 0; i + 1 < n; j++){

    if (a[i] > a[i + 1]){

    swap(a[i], a[i + 1]);swapped = true;

    }}

    } while (swapped);

    Shell sort for (int h = 8; h >= 1; h /= 2) // can be any decreasing sequence as long as it ends with h = 1{

    bool swapped;do{

    swapped = false;for (int i = 0; i + h < n; i++){

    if (a[i] > a[i + h]){

    swap(a[i], a[i + 1]);swapped = true;

    }}

    } while (swapped);}

  • 8/12/2019 Cs 32 Final Notes

    20/21

    Quick sort int partition(int a[], int low, int high){

    int pi = low;int pivot = a[low];do{

    while (low = 1){

    int pivotIndex = partition(a, from, to);quicksort(a, from, pivotIndex - 1);quicksort(a, pivotIndex + 1, to);

    }}

    Merge sort void merge(int a[], int n1, int n2){

    int *temp = new int[n1 + n2];int i = 0, j = 0, k = 0;int *b = a + n1; // This is the second half of arraywhile (i < n1 || j < n2){

    if (i == n1)temp[k++] = b[j++];

    else if (j == n2)temp[k++] = a[i++];

    else if (a[i] < b[j])temp[k++] = a[i++];

    elsetemp[k++] = b[j++];

    }for (i = 0; i < n1 + n2; i++)

    a[i] = temp[i];delete [] temp;

    }

    void mergesort(int a[], int from, int to){

    if (from - to

  • 8/12/2019 Cs 32 Final Notes

    21/21

    Heap sortvoid siftDown(int i, int n){

    // sift element i downwhile (left(i) < n){

    if (a[i] < a[left(i)] || a[i] < a[right(i)]){

    if (a[left(i)] > a[right(i)]){

    swap(a[i], a[left(i)]);i = left(i);

    }else{

    swap(a[i], a[right(i)]);i = right(i);

    }}else

    break;}

    }

    void heapSort(int a[], int n){

    // heapify// initial condition avoids all single node treesfor (int i = n / 2 - 1; i >= 0; i--)

    siftDown(i, n);// extract and reheapifyfor (int i = n - 1; i >= 0; i--){

    swap(a[0], a[i]);siftDown(0, i);

    }}