#include <string>
#include <fstream>
#include "QueType.h"
typedef char ItemType;
struct TreeNode;
enum OrderType {PRE_ORDER, IN_ORDER, POST_ORDER};
class TreeType {
public:
TreeType();
~TreeType();
TreeType(const TreeType& originalTree);
void MakeEmpty();
void operator=(const TreeType& originalTree);
bool IsEmpty() const;
bool IsFull() const;
int LengthIs() const;
void RetrieveItem(ItemType& item, bool& found);
void InsertItem(ItemType item);
void DeleteItem(ItemType item);
void ResetTree(OrderType order);
void GetNextItem (ItemType& item, OrderType order, bool& finished);
void Print(std::ofstream& outFile) const;
private:
TreeNode* root;
QueType preQue;
QueType inQue;
QueType postQue;
};
# 기본 생성자
TreeType::TreeType()
{
root = NULL;
}
# 입력 parameter로 tree가 주어졌을 때 생성자
TreeType::TreeType(const TreeType& originalTree)
{
CopyTree(root, originalTree.root);
}
void Destroy(TreeNode*& tree)
{
if (tree != NULL)
{
Destroy(tree->left);
Destroy(tree->right);
delete tree;
}
}
TreeType::~TreeType()
{
Destroy(root);
}
void TreeType::MakeEmpty()
{
Destroy(root);
root = NULL;
}
void CopyTree(TreeNode*& copy, const TreeNode* originalTree);
void TreeType::operator=(const TreeType& originalTree)
{
if (&originalTree == this)
return; // Ignore assigning self to self
Destroy(root); // Deallocate existing tree nodes
CopyTree(root, originalTree.root);
}
void CopyTree(TreeNode*& copy, const TreeNode* originalTree)
{
if (originalTree == NULL)
copy = NULL;
else
{
copy = new TreeNode;
copy->info = originalTree->info;
CopyTree(copy->left, originalTree->left);
CopyTree(copy->right, originalTree->right);
}
}
bool TreeType::IsEmpty() const
{
return root == NULL;
}
bool TreeType::IsFull() const
{
TreeNode* location;
try
{
location = new TreeNode;
delete location;
return false;
}
catch(std::bad_alloc exception)
{
return true;
}
}
int TreeType::LengthIs() const
{
return CountNodes(root);
}
int CountNodes(TreeNode* tree)
{
if (tree == NULL)
return 0;
else
return CountNodes(tree->left) + CountNodes(tree->right) + 1;
}
void Retrieve(TreeNode* tree, ItemType& item, bool& found);
void TreeType::RetrieveItem(ItemType& item, bool& found)
{
Retrieve(root, item, found);
}
void Retrieve(TreeNode* tree, ItemType& item, bool& found)
{
if (tree == NULL)
found = false; // item is not found.
else if (item < tree->info)
Retrieve(tree->left, item, found); // Search left subtree.
else if (item > tree->info)
Retrieve(tree->right, item, found);// Search right subtree.
else
{
item = tree->info; // item is found.
found = true;
}
}
void Insert(TreeNode*& tree, ItemType item);
void TreeType::InsertItem(ItemType item)
{
Insert(root, item);
}
void Insert(TreeNode*& tree, ItemType item)
{
if (tree == NULL)
{// Insertion place found.
tree = new TreeNode;
tree->right = NULL;
tree->left = NULL;
tree->info = item;
}
else if (item < tree->info)
Insert(tree->left, item); // Insert in left subtree.
else
Insert(tree->right, item); // Insert in right subtree.
}
child node를 지우는 경우
하나의 child node를 가지고 있는 node를 지우는 경우
두 개의 child node를 가지고 있는 node를 지우는 경우
DeleteItem Method 연습
Delete
DeleteNode
void DeleteNode(TreeNode*& tree);
void Delete(TreeNode*& tree, ItemType item);
void GetPredecessor(TreeNode* tree, ItemType& data);
void TreeType::DeleteItem(ItemType item)
{
Delete(root, item);
}
void Delete(TreeNode*& tree, ItemType item)
{
if (item < tree->info)
Delete(tree->left, item); // Look in left subtree.
else if (item > tree->info)
Delete(tree->right, item); // Look in right subtree.
else
DeleteNode(tree); // Node found; call DeleteNode.
}
void DeleteNode(TreeNode*& tree)
{
ItemType data;
TreeNode* tempPtr;
tempPtr = tree;
if (tree->left == NULL)
{
tree = tree->right;
delete tempPtr;
}
else if (tree->right == NULL)
{
tree = tree->left;
delete tempPtr;
}
else
{
GetPredecessor(tree->left, data); // GetPredecessor(tree->right, data);
tree->info = data;
Delete(tree->left, data); // Delete(tree->right, data);
}
}
void GetPredecessor(TreeNode* tree, ItemType& data)
{
while (tree->right != NULL)
tree = tree->right;
data = tree->info;
}
/*
void GetPredecessor(TreeNode* tree, ItemType& data)
{
while (tree->left != NULL)
tree = tree->left;
data = tree->info;
}
*/
void PreOrder(TreeNode*, QueType&);
void InOrder(TreeNode*, QueType&);
void PostOrder(TreeNode*, QueType&);
void TreeType::ResetTree(OrderType order)
{
switch (order)
{
case PRE_ORDER: PreOrder(root, preQue);
break;
case IN_ORDER: InOrder(root, inQue);
break;
case POST_ORDER: PostOrder(root, postQue);
break;
}
}
void PreOrder(TreeNode* tree, QueType& preQue)
{
if (tree != NULL)
{
preQue.Enqueue(tree->info);
PreOrder(tree->left, preQue);
PreOrder(tree->right, preQue);
}
}
void InOrder(TreeNode* tree, QueType& inQue)
{
if (tree != NULL)
{
InOrder(tree->left, inQue);
inQue.Enqueue(tree->info);
InOrder(tree->right, inQue);
}
}
void PostOrder(TreeNode* tree, QueType& postQue)
{
if (tree != NULL)
{
PostOrder(tree->left, postQue);
PostOrder(tree->right, postQue);
postQue.Enqueue(tree->info);
}
}
void TreeType::GetNextItem(ItemType& item, OrderType order, bool& finished)
{
finished = false;
switch (order)
{
case PRE_ORDER: preQue.Dequeue(item);
if (preQue.IsEmpty())
finished = true;
break;
case IN_ORDER: inQue.Dequeue(item);
if (inQue.IsEmpty())
finished = true;
break;
case POST_ORDER: postQue.Dequeue(item);
if (postQue.IsEmpty())
finished = true;
break;
}
}
void FindNode(TreeNode* tree, ItemType item, TreeNode*& nodePtr, TreeNode*& parentPtr)
{
nodePtr = tree;
parentPtr = NULL;
bool found = false;
while (nodePtr != NULL && !found)
{
if (item < nodePtr->info)
{
parentPtr = nodePtr;
nodePtr = nodePtr->left;
}
else if (item > nodePtr->info)
{
parentPtr = nodePtr;
nodePtr = nodePtr->right;
}
else
found = true;
}
}
void TreeType::InsertItem(ItemType item)
{
TreeNode* newNode;
TreeNode* nodePtr;
TreeNode* parentPtr;
newNode = new TreeNode;
newNode->info = item;
newNode->left = NULL;
newNode->right = NULL;
FindNode(root, item, nodePtr, parentPtr);
if (parentPtr == NULL) // Insert as root.
root = newNode;
else if (item < parentPtr->info)
parentPtr->left = newNode;
else parentPtr->right = newNode;
}
void GetPredecessor(TreeNode* tree, ItemType& data);
void Delete(TreeNode*& tree, ItemType item);
void DeleteNode(TreeNode*& tree)
{
ItemType data;
TreeNode* tempPtr;
tempPtr = tree;
if (tree->left == NULL)
{
tree = tree->right;
delete tempPtr;
}
else if (tree->right == NULL)
{
tree = tree->left;
delete tempPtr;
}
else
{
GetPredecessor(tree->left, data);
tree->info = data;
Delete(tree->left, data);
}
}
void Delete(TreeNode*& tree, ItemType item)
{
if (item < tree->info)
Delete(tree->left, item); // Look in left subtree.
else if (item > tree->info)
Delete(tree->right, item); // Look in right subtree.
else
DeleteNode(tree); // Node found; call DeleteNode.
}
void GetPredecessor(TreeNode* tree, ItemType& data)
{
while (tree->right != NULL)
tree = tree->right;
data = tree->info;
}
void TreeType::DeleteItem(ItemType item)
{
TreeNode* nodePtr;
TreeNode* parentPtr;
FindNode(root, item, nodePtr, parentPtr);
if (nodePtr == root)
DeleteNode(root);
else
if (parentPtr->left == nodePtr)
DeleteNode(parentPtr->left);
else DeleteNode(parentPtr->right);
}
Operation | Binary Search Tree | Array-based List | Linked List |
---|---|---|---|
Constructor | O(1) | O(1) | O(1) |
Destructor | O(N) | O(1) | O(N) |
IsFull | O(1) | O(1) | O(1) |
IsEmpty | O(1) | O(1) | O(1) |
RetrieveItem | O(logN) | O(logN) | O(N) |
InsertItem | O(logN) | O(N) | O(N) |
DeleteItem | O(logN) | O(N) | O(N) |
TreeNode* TreeType::PtrToSuccessor(TreeNode*& tree)
{
if (tree->left != NULL)
PtrToSuccessor(tree->left);
else
{
TreeNode* tempPtr = tree;
tree = tree->right;
return tempPtr;
}
}
TreeNode* TreeType::PtrToSuccessor(TreeNode*& tree)
{
while (tree->left == NULL)
tree = tree->left;
TreeNode* tempPtr = tree;
tree = tree->right;
return tempPtr;
}
bool Imp_IsBST(TreeNode* tree, ItemType& min, ItemType& max);
bool TreeType::IsBST()
{
ItemType min, max;
return Imp_IsBST(root, min, max);
}
bool Imp_IsBST(TreeNode* tree, ItemType& min, ItemType& max) {
bool isBST;
if (tree == NULL)
return true;
if (tree->left != NULL) {
char left_max = tree->info;
isBST = Imp_IsBST(tree->left, min, left_max);
if (!isBST || tree->info <= min || left_max > tree->info)
return false;
}
if (tree->right != NULL) {
char right_min = tree->info;
isBST = Imp_IsBST(tree->right, right_min, max);
if (!isBST || tree->info >= max || right_min < tree->info)
return false;
}
min = (tree->left == NULL) ? tree->info : min;
max = (tree->right == NULL) ? tree->info : max;
return true;
}
int Imp_LeafCount(TreeNode* tree);
int TreeType::LeafCount()
{
return Imp_LeafCount(root);
}
int Imp_LeafCount(TreeNode* tree)
{
if (tree == NULL)
return 0;
else if (tree->left == NULL && tree->right == NULL)
return 1;
else
return Imp_LeafCount(tree->left) + Imp_LeafCount(tree->right);
}
int Imp_SingleParentCount(TreeNode* tree);
int TreeType::SimgleParentCount()
{
return Imp_SingleParentCount(root);
}
int Imp_SingleParentCount(TreeNode* tree)
{
if (tree == NULL)
return 0;
else if (tree->left == NULL && tree->right != NULL)
return 1 + Imp_SingleParentCount(tree->right);
else if (tree->left != NULL && tree->right == NULL)
return 1 + Imp_SingleParentCount(tree->left);
else
return Imp_SingleParentCount(tree->left) + Imp_SingleParentCount(tree->right);
}
TreeNode* TreeType::PtrToSuccessor(TreeNode*& tree)
{
if (tree->left != NULL)
PtrToSuccessor_re(tree->left);
else
{
TreeNode* tempPtr = tree;
tree = tree->right;
return tempPtr;
}
}
void DeleteNode(TreeNode*& tree)
{
ItemType data;
TreeNode* tempPtr;
tempPtr = tree;
if (tree->left == NULL)
{
tree = tree->right;
delete tempPtr;
}
else if (tree->right == NULL)
{
tree = tree->left;
delete tempPtr;
}
else
{
PtrToSuccess(tree->right, data);
tree->info = data;
Delete(tree->right, data); // Delete predecessor node.
}
}
bool Imp_Ancestor_re(TreeNode* tree, ItemType value);
void TreeType::Ancestors_re(ItemType value)
{
Imp_Ancestor_re(root, value);
}
bool Imp_Ancestor_re(TreeNode* tree, ItemType value)
{
bool found = false;
if (tree == NULL)
return false;
if (tree->info == value)
return true;
if (tree->info < value)
{
found = Imp_Ancestor_re(tree->right, value);
}
else
{
found = Imp_Ancestor_re(tree->left, value);
}
if (found)
{
std::cout << tree->info << std::endl;
return found;
}
}
void TreeType::Ancestors_iter(ItemType value)
{
bool found = false;
QueType path;
TreeNode* currentNode = root;
while (!found && currentNode == NULL)
{
if (currentNode->info == value)
found = true;
else
{
path.Enqueue(currentNode->info);
if (value > currentNode->info)
currentNode = currentNode->right;
else
currentNode = currentNode->left;
}
}
if (found)
{
while (!path.IsEmpty())
{
ItemType item;
path.Dequeue(item);
std::cout << item << std::endl;
}
}
}
int Smaller(TreeType tree, int value)
{
ItemType item;
bool finished = false;
int count = 0;
tree.ResetTree(IN_ORDER); // IN_ORDER는 Sorted 형태로 저장됨
while (!finished)
{
tree.GetNextItem(item, IN_ORDER, finished);
if (item < value)
count++;
else
finished = true;
}
return count;
}
void AddElement(TreeType& tree, int Array[], int from, int to);
void MakeTree(TreeType& tree, SortedType<int>& list);
void AddElement(TreeType& tree, int Array[], int from, int to) {
int mid;
if (from <= to) {
mid = (from + to) / 2;
tree.InsertItem(Array[mid]);
cout << Array[mid] << endl;
AddElement(tree, Array, mid + 1, to);
AddElement(tree, Array, from, mid - 1);
}
}
void MakeTree(TreeType& tree, SortedType<int>& list) {
int length = list.LengthIs();
int* array = new int[length];
int item_info;
int i;
list.ResetList();
for (i = 0; i < length; i++) {
list.GetNextItem(item_info);
array[i] = item_info;
}
AddElement(tree, array, 0, length - 1);
delete[] array;
}
class TreeNode:
def __init__(self, info):
self.info = info
self.left = None
self.right = None
class BST():
def __init__(self):
self.root = None
self.order_list = []
def is_empty(self):
return (self.root == None)
def count_nodes(self, tree):
if (tree == None):
return 0
else:
return 1 + self.count_nodes(tree.left) + self.count_nodes(tree.right)
def length_is(self):
return self.count_nodes(self.root)
def insert(self, item):
self.root = self.insert_item(self.root, item)
return self.root is not None
def insert_item(self, node, item):
if node is None:
node = TreeNode(item)
else:
if item <= node.info:
node.left = self.insert_item(node.left, item)
else:
node.right = self.insert_item(node.right, item)
return node
def inorder(self, node):
if(node != None) :
self.inorder(node.left)
self.order_list.append(node.info)
self.inorder(node.right)
def preorder(self, node):
if(node != None):
self.order_list.append(node.info)
self.preorder(node.left)
self.preorder(node.right)
def postorder(self, node):
if(node != None):
self.postorder(node.left)
self.postorder(node.right)
self.order_list.append(node.info)
def delete(self, item):
self.root = self.delete_node(self.root, item)
def delete_node(self, current, item):
if (current == None):
return current
if ( item == current.info):
if(current.left == None and current.right == None):
current = None
elif(current.left == None):
current = current.right
elif(current.right == None):
current = current.left
else:
data = 0
data = self.get_predecessor(data)
current = TreeNode(data)
elif ( item < current.info):
current.left = self.delete_node(current.left, item)
else:
current.right = self.delete_node(current.right, item)
return current
def get_predecessor(tree, data):
while(tree.right != None):
tree = tree.right
data = tree.info
return data
class NodeType:
def __init__(self, data):
self.info = data
self.left = None
self.right = None
class IterBST():
def __init__(self):
self.root = None
self.order_list = []
def insert(self, data):
newnode = NodeType(data)
parentPtr = self.find(data)
if(parentPtr == None):
self.root = newnode
elif (data < parentPtr.info):
parentPtr.left = newnode
else:
parentPtr.right = newnode
def find(self, key):
nodePtr, parentPtr, found = self.find_node(self.root, key)
return parentPtr
def find_node(self, root, key):
nodePtr = root
parentPtr = None
found = False
while(nodePtr != None and (not found)):
if(key < nodePtr.info):
parentPtr = nodePtr
nodePtr = nodePtr.left
elif (key > nodePtr.info):
parentPtr = nodePtr
nodePtr = nodePtr.right
else:
found = True
return nodePtr, parentPtr, found
def delete(self, key):
self.root = self.delete_node(self.root, key)
def delete_node(self, node, key):
if (node == None):
return node
if (key == node.info):
if(node.left == None and node.right == None):
node = None
elif(node.left == None):
node = node.right
elif(node.right == None):
node = node.left
else:
data = 0
data = self.get_predecessor(data)
node = NodeType(data)
elif (key < node.info):
node.left = self.delete_node(node.left, key)
else:
node.right = self.delete_node(node.right, key)
return node
def inorder(self, node):
if(node != None) :
self.inorder(node.left)
self.order_list.append(node.info)
self.inorder(node.right)
def preorder(self, node):
if(node != None):
self.order_list.append(node.info)
self.preorder(node.left)
self.preorder(node.right)
def postorder(self, node):
if(node != None):
self.postorder(node.left)
self.postorder(node.right)
self.order_list.append(node.info)
def get_predecessor(tree, data):
while(tree.right != None):
tree = tree.right
data = tree.info
return data