Computer Science Notes

Notes From CS Undergrad Courses FSU

This project is maintained by awa03

A tree is a connected graph with no cycles. Between any two vertices, there is exactly one path.

Rooted Tree: is a graph G such that:

Path from node $n_1$ to $n_k$


Rooted Tree Recursively


Tree Traversal

Preorder

  1. Visit Vertex
  2. Visit Child Vertices (Recursive)

==DFS should be used==

Traversal Example
void listAll (int depth = 0) const{
	printName(depth);
	if(isDir()){
	for each file c in this directory (for each child)
		c.listAll(depth + 1);
}

Postorder Traversal

  1. Visit child vertices
  2. Then visit vertex (Recursive)

==DFS should be used==

Traversal Example

int totalSize = sizeOfFile)(;)
if(isDir()){
	for each file c in this directory (for each child)
		totalSize += c.size();
	return totalSize;
}

Level Order Traversal

  1. Visit all vertices in level
  2. Starting with level one and increasing (Use a queue, not recursive)

==BFS should be used==

Inorder Traversal

  1. Left Child
  2. Vertex
  3. Right Child (Recursive)

==DFS should be used==


Binary Trees

A binary tree is a rooted tree in which no vertex has more than two children, left and right child nodes

struct Node {
	Obj element;
	Node* left;
	Node* right;
}

Complete Binary Tree: A binary tree is complete iff every layer except possibly the bottom is fully populated with vertices. In addition, all nodes at the bottom level must occupy the leftmost spots consecutively.

Satisfies

Why is this this important

This ==significantly reduces== the search algorithms time complexity. Rather than needing to search a descending path in ==N==, it will be in ==Log (N)==. Since the tree is balanced to a degree. We know the height. For instance if we had a billion nodes stored within a tree, if complete there would only be a depth of ~31, if it is not then the depth could lead to a stack overflow, due to recursive calls overloading the stack, possible 1 billion nodes called!


Vector Representation

/* parent      */     v[k] = v[(k-1)/2]
/* left child  */     v[k] = v[2*k + 1]
/* right child */     v[k] = v[2*k + 2]

A vector is much easier to store, and we can use random access! It is a convenient way, but it necessitates the tree to be complete.