View
212
Download
0
Embed Size (px)
Citation preview
CS2420: Lecture 17
Vladimir KulyukinComputer Science Department
Utah State University
Outline
• Trees (Chapter 4)
Tree Traversals
• InOrder traversal
• PreOrder traversal
• PostOrder traversal
• Level traversal
InOrder Traversal
• If the current node is not empty,– Traverse the left sub-tree;– Traverse the current node;– Traverse the right sub-tree.
InOrder Traversal in C++template <class T>void processNode(CBinaryTreeNode<T> *node) {
// some code that processes the node somehow; }// We assume that we have implemented the getter and setter methods// for CBinaryTreeNode.template <class T>class CBinaryTreeNode { public: CBinaryTreeNode<T> *getLeftChild() const { …} CBinaryTreeNode<T> *getRightChild() const { … } void setLeftChild() { … } void setRightChild() { … }};
InOrder Traversal in C++
template <class T>voidCBinaryTree<T>::inOrder(CBinaryTreeNode<T> *node){
if ( node != NULL ) {inOrder(node->getLeftChild());processNode(node);inOrder(node->getRightChild());
}}
PreOrder Traversal
• If the current node is not empty,– Traverse the current node;– Traverse the left sub-tree;– Traverse the right sub-tree.
PreOrder Traversal in C++
template <class T>voidCBinaryTree<T>::preOrder(CBinaryTreeNode<T> *node){
if ( node != NULL ) {processNode(node);preOrder(node->getLeftChild());preOrder(node->getRightChild());
}}
PostOrder Traversal
• If the current node is not empty,– Traverse the left sub-tree;– Traverse the right sub-tree;– Traverse the current node.
PostOrder Traversal in C++
template <class T>voidCBinaryTree<T>::postOrder(CBinaryTreeNode<T> *node){
if ( node != NULL ) {postOrder(node->getLeftChild());postOrder(node->getRightChild());processNode(node);
}}
Level Traversal
• Initialize a queue of binary tree nodes.• Add the root to the queue.• While the queue is not empty
– Pop the node from the queue;– Process the node;– If the popped node’s left child is not empty,
add it to the queue;– If the popped node’s right child is not empty,
add it to the queue;– Decide what to do with the popped node.
Deleting a Binary Tree
template <class T>voidCBinaryTree<T>::deleteTree(CBinaryTreeNode<T> *node){
if ( node != NULL ) {deleteTree(node->GetLeftChild());deleteTree(node->GetRightChild());delete node;
}}
Basic Questions 3 and 4 from Lecture 1
• How can I store/organize data efficiently?
• How can I retrieve/search data efficiently?
Collections and Dictionaries
• A Collection/Dictionary has a set of N elements each of which is indexed under a possibly unique key.
• The task of a collection/dictionary data structure is to insert/delete/retrieve an element given its key in the most efficient way.
Collections
• Lists, arrays, queues, and stacks are collections.• List
– Insertion: O(N); Deletion: O(N); Search: O(N).• Array
– Insertion: O(N); Deletion: O(N); Search: O(1).• Queue
– Insertion: O(1); Limited Deletion: O(1); Search: Not Available.
• Stack– Insertion: O(1): Limited Deletion: O(1); Search: Not
Available.
Binary Search Tree: A Collection
• A Binary Search Tree (BST) is an empty binary tree.
• A BST is a non-empty binary tree such that– The keys in the left sub-tree are smaller than
the root’s key;– The keys in the right sub-tree are larger than
the root’s key;– The left and right sub-trees are BSTs.
Binary Search Tree ≠ Binary Tree
• Binary Search Tree ≠ Binary Tree.
• Every binary search tree is a binary tree.
• But not every binary tree is a binary search tree.
Example
45
50
12 37
45
71
34
3712
5034
46
A BST Not A BST
BST with Duplicates
• If the key comparison is relaxed to <= or >=, the BST will contain duplicates.
• Two implementations of BST with duplicates:– Linked nodes;– Duplicate counters.
BT Node: Version 1
KEY
DATA
LEFTCHILDPTR
RIGHTCHILDPTR
BT Node: Version 1.A
KEY
DATA
LEFTCHILDPTR
RIGHTCHILDPTR
Key and Dataare of the same type.
BT Node: Version 1.Atemplate <class T>class CBinaryTreeNode { friend void ProcessNode(CBinaryTreeNode<T> *node);
protected: T m_Key; T m_Data; CBinaryTreeNode<T> * m_LeftChild; CBinaryTreeNode<T> * m_RightChild;
public:CBinaryTreeNode<T>* GetLeftChild() const;
CBinaryTreeNode<T>* GetRightChild() const;void SetLeftChild(CBinaryTreeNode<T> *node);
void SetRightChild(CBinaryTreeNode<T> *node); T GetData() const { return m_Data; }
T GetKey() const { return m_Key; }};
BT Node: Version 1.B
KEY
DATA
LEFTCHILDPTR
RIGHTCHILDPTR
Key and Dataare different types.
BT Node: Version 1.Btemplate <class Key, class Data>class CBinaryTreeNode { friend void ProcessNode(CBinaryTreeNode<Key, Data> *node);
protected: Key m_Key; Data m_Data; CBinaryTreeNode<Key, Data> * m_LeftChild; CBinaryTreeNode<Key, Data> * m_RightChild;
public:CBinaryTreeNode<Key, Data>* GetLeftChild() const;
CBinaryTreeNode<Key, Data>* GetRightChild() const;void SetLeftChild(CBinaryTreeNode<Key, Data> *node);
void SetRightChild(CBinaryTreeNode<Key, Data> *node); Data GetData() const { return m_Data; }
Key GetKey() const { return m_Key; }};
BT Node: Version 2
KEY = DATA
LEFTCHILDPTR
RIGHTCHILDPTR
BT Node: Version 2template <class T>class CBinaryTreeNode {
protected: T m_Data; CBinaryTreeNode<Key, Data> * m_LeftChild; CBinaryTreeNode<Key, Data> * m_RightChild;
public: CBinaryTreeNode(); CBinaryTreeNode(const T& data); CBinaryTreeNode(const T& data, CBinaryTreeNode<T> *left, CBinaryTreeNode<T> *right); CBinaryTreeNode<T>* GetLeftChild() const; CBinaryTreeNode<T>* GetRightChild() const;
void SetLeftChild(CBinaryTreeNode<T> *node); void SetRightChild(CBinaryTreeNode<T> *node); T GetData() const { return m_Data; }};
Binary Search Tree Interfacetemplate <class T>class CBinarySearchTree : public CBinaryTree<T>{
protected: CBinaryTreeNode<T> *m_Current; int m_Size; // number of nodes in the tree.public: // method 1 bool Find(T& item); // method 2 CBinaryTreeNode<T>*
FindNode(const T &item, CBinaryTreeNode<T>* &parent) const; // method 3 void Insert(const T& item); // method 4 CBinaryTreeNode<T>* Delete(const T& item);
};
Finding a Node and its Parenttemplate <class T>CBinaryTreeNode<T>* CBinarySearchTree<T>::FindNode(const T& item, CBinaryTreeNode<T>* &parent) const{
CBinaryTreeNode<T> *current = m_Root; parent = NULL;
while ( current != NULL ) {if ( item == current->GetData() ) {
break;}else {
parent = current;if ( item < current->GetData() ) { current = current->GetLeftChild();}else { current = current->GetRightChild();}
}}return current;
}
Finding an Item in a BST
• Given a key K and a BST T with the root R– If T is empty, return false.– If R contains K, return R’s data and true.– If K is less than R’s key, search in the left
sub-tree.– If K is greater than R’s key, search in the right
sub-tree.
Finding an Item in a BSTtemplate <class T>bool CBinarySearchTree<T>::Find(T& item){
CBinaryTreeNode<T> *parent;
m_Current = FindNode(item, parent);
if ( m_Current != NULL ) {item = m_Current->GetData();return true;
}else {
return false;}
}
Inserting an Item
• Given a key K, and a BST T– See if the BST already contains an item under
K. If yes, do nothing.– If no such element is found, insert K at the
point where the search terminated.
Inserting an Itemtemplate <class T> void CBinarySearchTree<T>::Insert(const T& item) {
CBinaryTreeNode<T> *current = m_Root, *parent = NULL;if ( Find(item) == true ) return;while ( current != NULL ) {
parent = current;if ( item < current->GetData() ) current = current->GetLeftChild();else current = current->GetRightChild();
}CBinaryTreeNode<T> *addedNode = new CBinaryTreeNode<T>(item);
if ( parent == NULL )m_Root = addedNode;
else if ( item < parent->GetData() )parent->SetLeftChild(addedNode);
elseparent->SetRightChild(addedNode);
m_Size++;}