• toc {:toc}

Binary Tree

  • Property1 : ๊ฐ ๋…ธ๋“œ๋“ค์€ ์ตœ๋Œ€ 2๊ฐœ์˜ ์ž์‹์„ ๊ฐ–๋Š”๋‹ค.

  • Property2 : ๋ฃจํŠธ๋ถ€ํ„ฐ ๋‹ค๋ฅธ ๋…ธ๋“œ๊นŒ์ง€ ์œ ์ผํ•œ ๊ธธ์„ ๊ฐ–๋Š”๋‹ค.

  • ํฌํ™” ์ด์ง„ ํŠธ๋ฆฌ(Perfect Binary Tree) : ๋ฆฌํ”„ ๋…ธ๋“œ๊ฐ€ ์•„๋‹Œ ๋ชจ๋“  ๋…ธ๋“œ๋“ค์€ 2๊ฐœ์˜ ์ž์‹์„ ๊ฐ€์ง€๊ณ  ๋ชจ๋“  ๋ฆฌํ”„ ๋…ธ๋“œ๊ฐ€ ์ฐจ ์žˆ๋Š” ํŠธ๋ฆฌ๋ฅผ ๋งํ•œ๋‹ค.

    • i ๋ ˆ๋ฒจ์—์„œ ์ตœ๋Œ€ ๋…ธ๋“œ :
  • ์ด์ง„ ๊ฒ€์ƒ‰ ํŠธ๋ฆฌ

    • ๋ชจ๋“  ๋…ธ๋“œ๋“ค์€ ๊ฒน์น˜์ง€ ์•Š๋Š” ๊ณ ์œ ํ•œ ๋ฐ์ดํ„ฐ ๊ฐ’์„ ๊ฐ€์ง„๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.
    • ํ‚ค๊ฐ’์€ ํฌ๊ณ  ์ž‘๊ณ ๋ฅผ ๋น„๊ตํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์ž‘์œผ๋ฉด ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ, ํฌ๋ฉด ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋กœ ์ด๋™ํ•œ๋‹ค.
  • ๊ฒ€์ƒ‰ ์‹œ๊ฐ„

    • ์ตœ์•…์˜ ๊ฒฝ์šฐ - O(N)
    • ์ตœ์„ ์˜ ๊ฒฝ์šฐ - O(logN)
template<class ItemType>
struct TreeNode;
 
enum OrderType {PRE_ORDER, IN_ORDER, POST_ORDER};
 
template<class ItemType>
class TreeType {
public:
	TreeType();
	~TreeType();
	TreeType(const TreeType<ItemType>&);
	void operator=(const TreeType<ItemType>&);
	void MakeEmpty();
	bool IsEmpty() const;
	bool IsFull() const;
	int LengthIs() const;
	void RetrieveItem(ItemType& item, bool& found);
	void InsertItem(ItemType);
	void DeleteItem(ItemType);
	void ResetTree(OrderType);
	void GetNextItem(ItemType&, OrderType, bool&);
	void PrintTree(ofstream&) const;
private:
	TreeNode<ItemType>* root;
};
  • ๋…ธ๋“œ ๊ฐœ์ˆ˜ ์นด์šดํŠธ
int CountNodes(TreeNode* tree){
	if (tree == NULL)
		return 0;
	else
		return CountNodes(tree->left) + CountNodes(tree->right) + 1;
}
  • ๋…ธ๋“œ ์กด์žฌํ•˜๋Š”์ง€ ์ฐพ๊ธฐ
void RetrieveItem(ItemType& item, bool& found){
	Retrieve(root, item, found);
}
 
void Retrieve(TreeNode* tree, ItemType& item, bool& found){
	if (tree == NULL)
		found=false;
	else if (tree->info > item)
		Retrieve(tree->left, item, found);
	else if (tree->info < item)
		Retrieve(tree->right, item, found);
	else{
		found = true;
	}
}
  • ๋…ธ๋“œ ์‚ฝ์ž…
void Insert(TreeNode*& tree, ItemType item){
	if (tree == NULL){
		tree = new TreeNode;
		tree->right = NULL;
		tree->left = NULL;
		tree->info = item;
	}
	else if (tree->info > item)
		Insert(tree->left, item);
	else
		Insert(tree->right, item);
}
  • ๋…ธ๋“œ ์‚ฝ์ž…์€ ์œ„์น˜๋ฅผ ์ฐพ์•„๊ฐ€์„œ ํฌ์ธํ„ฐ ์กฐ์ •์„ ํ•ด์ค€๋‹ค.

  • ๋˜ํ•œ, ์ด์ „ Sorted List์™€ ๊ฐ™์ด ํฌ์ธํ„ฐ์˜ ์ฃผ์†Œ๋ฅผ ์ง€์ •ํ•ด์ค€๋‹ค. ์ฆ‰, ๋งŒ์•ฝ treeโ†’info > item ์ธ ๊ฒฝ์šฐ treeโ†’left๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜๊ฒจ์ฃผ๋Š”๋ฐ, ์ด๋•Œ treeโ†’left์— new๋กœ ๋™์  ํ• ๋‹น๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ๋ถ€๋ชจ์™€์˜ ํฌ์ธํ„ฐ ์—ฐ๊ฒฐ์„ tree == NULL ์กฐ๊ฑด์—์„œ ํ•ด์ฃผ์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

  • ๋…ธ๋“œ ์‚ญ์ œ

    • ์ž์‹์ด ์—†๋Š” ๊ฒฝ์šฐ
    • ์ž์‹์ด ํ•˜๋‚˜๋งŒ ์žˆ๋Š” ๊ฒฝ์šฐ
    • ์ž์‹์ด ๋‘ ๊ฐœ ์žˆ๋Š” ๊ฒฝ์šฐ
void DeleteItem(ItemType item){
	Delete(root, item);
}
 
void Delete(TreeNode*& tree, ItemType item){
// ํ•ด๋‹น item์ด ์žˆ๋Š” ์œ„์น˜๊นŒ์ง€ ์ด๋™ํ•œ๋‹ค.
 
    if (tree == NULL){
        return;
    }
    
    if (item < tree->info){
        Delete(tree->left, item);
    }
    else if (item > tree->info){
        Delete(tree->right, item);
    }
    else{ // ์ฐพ์œผ๋ฉด DeleteNode๋ฅผ ํ•œ๋‹ค.
        DeleteNode(tree);
    }
}
 
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{
        while(tree->right != NULL){ // ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋งจ ์˜ค๋ฅธ์ชฝ ๋ฆฌํ”„ ์ฐพ๊ธฐ
	        tree = tree->right;
        }
		data = tree->info;
 
		tree->info = data;         // ๋ฆฌํ”„ ๋…ธ๋“œ ์ง€์šด์ž๋ฆฌ๋กœ ์ด๋™
        Delete(tree->left, data);  // ์ฐพ์€ ๋ฆฌํ”„ ์ง€์šฐ๊ธฐ
    }
}

Recursive Print

Inorder

  • LDR (Left, Data, Right) ์ˆœ์„œ
  • ํฌ๊ธฐ ์ˆœ์„œ๋Œ€๋กœ ์ถœ๋ ฅํ•˜๋Š” ๊ฒฝ์šฐ inorder ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ๋‹ค.
void InOrder(TreeNode* tree, QueType& inQue){
	if(tree != NULL){
		InOrder(tree->left, inQue)
		inQue.Enqueue(tree->info)
		InOrder(tree->right, inQue)
	}
}

Preorder

  • DLR (Data, Left, Right) ์ˆœ์„œ
  • Constructor๋ฅผ ๋งŒ๋“ค ๋•Œ ๋ฃจํŠธ ๋…ธ๋“œ๋ถ€ํ„ฐ ๋งŒ๋“ค์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— preorder๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • DFS์™€ ๊ฐ™๋‹ค.
void PreOrder(TreeNode* tree, QueType& preQue){
	if(tree != NULL){
		preQue.Enqueue(tree->info);
		PreOrder(tree->left, preQue);
		PreOrder(tree->right, preQue);
	}
}

Postorder

  • LRD (Left, Right, Data) ์ˆœ์„œ
  • Destructor๋ฅผ ๋งŒ๋“ค ๋•Œ ๋ฆฌํ”„ ๋…ธ๋“œ๋ถ€ํ„ฐ ์‚ญ์ œํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— postorder ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•œ๋‹ค.
void PostOrder(TreeNode* tree, QueType& postQue){
	if(tree != NULL){
		PostOrder(tree->left, postQue);
		PostOrder(tree->right, postQue);
		postQue.Enqueue(tree->info);
	}
}

Iterative Method

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)
		root = newNode;
	else if (item < parentPtr->info)
		parentPtr->left = newNode;
	else parentPtr->right = newNode;
}
 
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);
}