數據結構學習五:二叉樹

二叉樹

          二叉樹是一棵樹,其中每個節點的孩子最多爲2個。性質:平均二叉樹的深度要比節點數N小得多,對於特殊類型的二叉樹,即二叉查找樹其深度的平均值是O(logN)。

實現

       因爲二叉樹最多有兩個孩子,所以可以定義兩個指針指向他們。二叉樹的聲明在結構上類似於雙鏈表的聲明。

定義如下

/*
* 二叉樹聲明
*/
struct TreeNode
{
	int Data;
	TreeNode* Left;
	TreeNode* Right;
};


下面以二叉查找樹的實現舉例

#pragma once
#include"TreeNode.h"

/*
*二叉查找樹
*/
class BinarySearchTree
{
private:
	TreeNode* _root;
public:
	BinarySearchTree();
	~BinarySearchTree();

public:
	void MakeEmpty();
	TreeNode* FindData(int data, TreeNode* t);
	TreeNode* FindMin(TreeNode* t);
	TreeNode* FindMax(TreeNode* t);
	bool Insert(int data);
	bool Delete(int data);
	void ShowTree();
private:
	TreeNode* Find(int data);
	void MakeEmptyTree(TreeNode* t);
	TreeNode* SubInsert(int data, TreeNode* t);
	TreeNode* SubDelete(int data, TreeNode* t);

	/*print tree*/
	void PrintBinaryTree(TreeNode *root);
	void PrintNode(vector<TreeNode*> &nodes, int level, int max_level);
	void PrintWhiteSpaces(int num);
	bool IsAllElementsNULL(const vector<TreeNode*> &nodes);
	int MaxLevel(TreeNode *root);
	int max(int a, int b);
};

#include "stdafx.h"
#include "BinarySearchTree.h"


BinarySearchTree::BinarySearchTree()
{
}


BinarySearchTree::~BinarySearchTree()
{
}

void BinarySearchTree::MakeEmpty()
{
	if (_root != nullptr)
	{
		MakeEmptyTree(_root);
	}
	return;
}

TreeNode* BinarySearchTree::FindData(int data,TreeNode* t)
{
	if (t == nullptr)
	{
		return nullptr;
	}
	if (data < t->Data)
	{
		return FindData(data, t->Left);
	}
	else if (data > t->Data)
	{
		return FindData(data, t->Right);
	}
	else
	{
		return t;
	}
}

TreeNode* BinarySearchTree::FindMin(TreeNode* t)
{
	if (t == nullptr)
	{
		return nullptr;
	}
	else if (t->Left == nullptr)
	{
		return t;
	}
	else
	{
		return FindMin(t->Left);
	}
}

TreeNode* BinarySearchTree::FindMax(TreeNode* t)
{
	if (t != nullptr)
	{
		while (t->Right != nullptr)
		{
			t = t->Right;
		}
	}
	return t;
}

bool BinarySearchTree::Insert(int data)
{
	_root=SubInsert(data, _root);
	if (nullptr == _root)
	{
		return false;
	}
	return true;
}

bool BinarySearchTree::Delete(int data)
{
	if (_root == nullptr)
	{
		return false;
	}
	_root=SubDelete(data, _root);
	return true;
}



void BinarySearchTree::ShowTree()
{
	PrintBinaryTree(_root);
}

TreeNode * BinarySearchTree::Find(int data)
{
	return nullptr;
}

void BinarySearchTree::MakeEmptyTree(TreeNode * t)
{
	if (t != nullptr)
	{
		MakeEmptyTree(t->Left);
		MakeEmptyTree(t->Right);
		delete t;
	}
}

TreeNode* BinarySearchTree::SubInsert(int data, TreeNode * t)
{
	if (nullptr == t)
	{
		t = new TreeNode();
		if (nullptr == t)
		{
			return nullptr;
		}
		else
		{
			t->Data = data;
			t->Left = t->Right = nullptr;
		}
	}
	else if (data < t->Data)
	{
		t->Left = SubInsert(data, t->Left);
	}
	else if (data > t->Data)
	{
		t->Right = SubInsert(data, t->Right);
	}
	return t;
}

TreeNode * BinarySearchTree::SubDelete(int data, TreeNode * t)
{
	TreeNode* tempCell;
	if (t == nullptr)
	{
		return nullptr;
	}
	else if (data < t->Data)
	{
		t->Left = SubDelete(data, t->Left);
	}
	else if (data > t->Data)
	{
		t->Right = SubDelete(data, t->Right);
	}
	else if (t->Left && t->Right)
	{
		tempCell = FindMin(t->Right);
		t->Data = tempCell->Data;
		t->Right = SubDelete(t->Data, t->Right);
	}
	else
	{
		tempCell = t;
		if (t->Left == nullptr)
		{
			t = t->Right;
		}
		else if (t->Right == nullptr)
		{
			t = t->Left;
		}
		delete tempCell;
	}
	return t;
}


#pragma region print binary tree
/* print binary tree*/
// wrapper function  
void BinarySearchTree::PrintBinaryTree(TreeNode *root)
{
	int max_level = MaxLevel(root);
	vector<TreeNode*> nodes;

	nodes.push_back(root);

	PrintNode(nodes, 1, max_level);
}


int BinarySearchTree::MaxLevel(TreeNode *root)
{
	if (root == NULL) return 0;
	return max(MaxLevel(root->Left), MaxLevel(root->Right)) + 1;
}

void BinarySearchTree::PrintNode(vector<TreeNode*> &nodes, int level, int max_level)
{
	if (nodes.empty() || IsAllElementsNULL(nodes)) return; // exit  

	int floor = max_level - level;
	int endge_lines = 1 << (max(floor - 1, 0));
	int first_spaces = (1 << floor) - 1;
	int between_spaces = (1 << (floor + 1)) - 1;

	PrintWhiteSpaces(first_spaces);

	// print the 'level' level   
	vector<TreeNode*> new_nodes;
	vector<TreeNode*>::const_iterator it = nodes.begin();
	for (; it != nodes.end(); ++it) {
		if (*it != NULL) {
			cout << (*it)->Data;
			new_nodes.push_back((*it)->Left);
			new_nodes.push_back((*it)->Right);
		}
		else {
			new_nodes.push_back(NULL);
			new_nodes.push_back(NULL);
			cout << " ";
		}
		PrintWhiteSpaces(between_spaces);
	}
	cout << endl;

	// print the following /s and \s  
	for (int i = 1; i <= endge_lines; ++i) {
		for (int j = 0; j<nodes.size(); ++j) {
			PrintWhiteSpaces(first_spaces - i);
			if (nodes[j] == NULL) {
				PrintWhiteSpaces(endge_lines + endge_lines + i + 1);
				continue;
			}
			if (nodes[j]->Left != NULL)
				cout << "/";
			else
				PrintWhiteSpaces(1);

			PrintWhiteSpaces(i + i - 1);

			if (nodes[j]->Right != NULL)
				cout << "\\";
			else
				PrintWhiteSpaces(1);

			PrintWhiteSpaces(endge_lines + endge_lines - i);
		}
		cout << endl;
	}

	PrintNode(new_nodes, level + 1, max_level);

}

// test whether all elements in vector are NULL  
bool BinarySearchTree::IsAllElementsNULL(const vector<TreeNode*> &nodes)
{
	vector<TreeNode*>::const_iterator it = nodes.begin();

	while (it != nodes.end()) {
		if (*it) return false;
		++it;
	}
	return true;
}

void BinarySearchTree::PrintWhiteSpaces(int num)
{
	for (int i = 0; i<num; ++i)
		cout << " ";
}


int BinarySearchTree::max(int a, int b)
{
	return a > b ? a : b;
}
#pragma endregion

測試類

#pragma once
#include "stdafx.h"
#include "BinarySearchTree.h"
#include "MultiTreeNodeOperation.h"

void WaitUserPressAKey();

int main()
{
	int arrs[] = { 6,2,8,1,4,3};
	BinarySearchTree* myTree = new BinarySearchTree();
	cout << "insert 6,2,8,1,4,3:" << endl;
	for each (int item in arrs)
	{
		myTree->Insert(item);
	}
	myTree->ShowTree();
	
	myTree->Insert(5);
	cout << "insert 5:" << endl;
	myTree->ShowTree();
	myTree->Delete(4);
	cout << "delete 4:" << endl;
	myTree->ShowTree();


運行結果



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章