二叉查詢樹的實現——C++

samuelcoulee發表於2013-02-19

二叉查詢樹是比較基礎的資料結構,可實現排序、二分查詢等操作。

但是由於生成方式的侷限性(不控制平衡),當先後插入的關鍵字有序時,便會形成單支,嚴重影響效率和效能。(後續要實現的目標當然就是自平衡樹了,比如AVL、紅黑樹)

話不多說,直接貼原始碼。

 

標頭檔案(BinarySearchTree.h):

/***********************
 * BinarySearchTree.h
 **********************/

#pragma once

//節點定義.
typedef struct _BinaryTreeNode
{
	int data;
	struct _BinaryTreeNode *leftChild, *rightChild;
}BinaryTreeNode;


//二叉查詢樹類.
class BinarySearchTree
{
private:
	BinaryTreeNode* m_pRootNode;	//根節點

public:
	BinarySearchTree();
	~BinarySearchTree();

	//新增節點.
	bool AddNode(int data = 0);

	//前序遍歷.
	void PreOrderTraverse();
	//中序遍歷.
	void InOrderTraverse();
	//後序遍歷.
	void PostOrderTraverse();		

private:

	//插入節點,遞迴.
	void InsertNode(BinaryTreeNode* toNode, BinaryTreeNode* srcNode);
	
	//遞迴實現前序遍歷.
	void PreOrder(BinaryTreeNode* node);
	//遞迴實現中序遍歷.
	void InOrder(BinaryTreeNode* node);
	//遞迴實現後序遍歷.
	void PostOrder(BinaryTreeNode* node);

	//列印節點.
	void PrintNode(BinaryTreeNode* node);
	//建立新節點.
	BinaryTreeNode* CreateNewNode(int data);

	//刪除所有節點,在解構函式中呼叫.
	void DeleteAllNodes();
	//遞迴刪除節點.
	void DeleteNode(BinaryTreeNode* node);
};


 

實現檔案(BinarySearchTree.cpp):

/**
 * BinarySearchTree.cpp
 */

#include "BinarySearchTree.h"
#include <stdio.h>

BinarySearchTree::BinarySearchTree()
	:m_pRootNode(NULL)
{
}

BinarySearchTree::~BinarySearchTree()
{
	this->DeleteAllNodes();
}


bool BinarySearchTree::AddNode(int data/* = 0*/)
{
	BinaryTreeNode* newNode = this->CreateNewNode(data);
	if(!newNode)
		return false;

	if(!m_pRootNode)
	{
		m_pRootNode = newNode;
		return true;
	}

	this->InsertNode(m_pRootNode, newNode);
	return true;
}
void BinarySearchTree::InsertNode(BinaryTreeNode* toNode, BinaryTreeNode* srcNode)
{
	if(!toNode || !srcNode)
		return;

	if(srcNode->data <= toNode->data)
	{
		if(!toNode->leftChild)
		{
			toNode->leftChild = srcNode;
		}
		else
		{
			this->InsertNode(toNode->leftChild, srcNode);
		}
	}
	else
	{
		if(!toNode->rightChild)
		{
			toNode->rightChild = srcNode;
		}
		else
		{
			this->InsertNode(toNode->rightChild, srcNode);
		}
	}
}


void BinarySearchTree::PreOrderTraverse()
{
	this->PreOrder(m_pRootNode);
}
void BinarySearchTree::PreOrder(BinaryTreeNode* node)
{
	if(!node)
	{
		return;
	}

	this->PreOrder(node->leftChild);
	this->PrintNode(node);
	this->PreOrder(node->rightChild);
}


void BinarySearchTree::InOrderTraverse()
{
	this->InOrder(m_pRootNode);
}
void BinarySearchTree::InOrder(BinaryTreeNode* node)
{
	if(!node)
		return;

	this->PrintNode(node);
	this->InOrder(node->leftChild);
	this->InOrder(node->rightChild);
}


void BinarySearchTree::PostOrderTraverse()
{
	this->PostOrder(m_pRootNode);
}
void BinarySearchTree::PostOrder(BinaryTreeNode* node)
{
	if(!node)
		return;

	this->PostOrder(node->rightChild);
	this->PrintNode(node);
	this->PostOrder(node->leftChild);
}


BinaryTreeNode* BinarySearchTree::CreateNewNode(int data/* = 0*/)
{
	BinaryTreeNode* newNode = new BinaryTreeNode();

	if(newNode)
		newNode->data = data;

	return newNode;
}


void BinarySearchTree::PrintNode(BinaryTreeNode* node)
{
	if(!node)
		return;

	printf("%d ", node->data);
}

void BinarySearchTree::DeleteAllNodes()
{
	this->DeleteNode(m_pRootNode);
}
void BinarySearchTree::DeleteNode(BinaryTreeNode* node)
{
	if(!node)
		return;

	//自底向上.
	this->DeleteNode(node->leftChild);
	this->DeleteNode(node->rightChild);
	delete node;
}


 

測試檔案(TestBST.cpp)

/**
 * TestBST.cpp
 */
#include "BinarySearchTree.h"

#include <iostream>
#include <time.h>

using namespace std;

bool testBST(int nodeNum)
{
	BinarySearchTree* pBST = new BinarySearchTree();

	//以當前時間為隨機種子.
	srand((unsigned int)time(0));

	//新增指定個數的元素.
	cout<<"Insert: "<<endl;
	int tmpData;
	for(int i =0; i<nodeNum; ++i)
	{
		tmpData = rand();
		cout<<tmpData<<' ';

		if(!pBST->AddNode(tmpData))
		{
			return false;
		}
	}

	//遍歷.
	cout<<endl<<endl<<"PreOrder: "<<endl;
	pBST->PreOrderTraverse();
	cout<<endl<<endl<<"InOrder:"<<endl;
	pBST->InOrderTraverse();
	cout<<endl<<endl<<"PostOrder:"<<endl;
	pBST->PostOrderTraverse();

	//清理.
	delete pBST;
	return true;
}

int main()
{
	if(!testBST(10))
	{
		//cout<<endl<<"測試失敗."<<endl;
	}

	return 0;
}


 

執行結果:

 

=============================End===================================

 

 

相關文章