1. 程式人生 > >資料結構——二叉樹:基本二叉樹(C++)

資料結構——二叉樹:基本二叉樹(C++)

內容概要:

  • 二叉樹相關概念
  • 簡單二叉樹模板類的實現:二叉樹的遍歷、計算高度、計算節點數目
  • 注意事項

一、二叉樹相關概念:

第一部分:

  • 節點(node),根節點(root),左子樹(left subtree),右子樹(right suntree),子節點(children),父節點(parent);每一個非空二叉樹有一個根節點和左右子樹。
  • 路徑(path),路徑的長度(length),祖先(ancestor),深度(depth),高度(height),層數(level);其中 高度=深度+1=層數+1,根節點深度為0,層數為0,高度為1。
  • 葉節點(leaf):子樹均為空的節點。
  • 分支節點或內部節點(internal node):至少有一個非空子樹的節點。
  • 滿二叉樹(full binary tree):二叉樹中的每一個內部節點都有兩個非空子節點,其更嚴格的定義是高度為h的二叉樹,有2^h -1個節點

      picture10.4                            picture10.2                   

  • 完全二叉樹(complete binary tree):從二叉樹的根節點起,每一層從左到右依次填充

       picture10.3 picture10.4 picture10.5

第二部分:

  • 非空滿二叉樹的葉節點數等於其內部節點數加1(用數學歸納法證明)
  • 一棵非空二叉樹空子樹的數目等於其節點數目加1

二、CODE(測試環境:VS2017):

//BT.h

#ifndef BT_H
#define BT_H

#include<iostream>

template<typename E>
class BTNode
{
private:
	E key;
	BTNode*lc;
	BTNode*rc;

public:
	BTNode() { lc = rc = NULL; }
	BTNode(E k, BTNode*l = NULL, BTNode*r = NULL) { key = k; lc = l; rc = r; }
	~BTNode(){}

	E& element() { return key; }
	void setElement(const E&it) { key = it; }

	inline BTNode*left () const { return lc; }
	void setLeft(BTNode*l) { lc = l; }
	inline BTNode*right () const { return rc; }
	void setRight(BTNode*r) { rc = r; }

	bool isLeaf() const { return (lc == NULL) && (rc == NULL); }

	void traverse() const
	{
		if (isLeaf())
		{
			std::cout << "Leaf:" << key << endl;
		}
		else
		{
			std::cout << "Internal:" << key << endl;
			if (lc != NULL)
				lc->traverse();
			if (rc != NULL)
				rc->traverse();
		}
	}
};

#endif // !BT_H
//《資料結構與演算法分析(第三版)》

//main.cpp

#include<iostream>
#include"BT.h"
using namespace std;

template<typename E>
void preOrder(BTNode<E>*root)
{
	if (root == NULL)
		return;
	cout << root->element() << "	";//do something
	preOrder(root->left());
	preOrder(root->right());
}

template<typename E>
void inOrder(BTNode<E>*root)
{
	if (root == NULL)
		return;
	inOrder(root->left());
	cout << root->element() << "	";//do something
	inOrder(root->right());
}

template<typename E>
void postOrder(BTNode<E>*root)
{
	if (root == NULL)
		return;
	postOrder(root->left());
	postOrder(root->right());
	cout << root->element() << "	";//do something
}

template<typename E>
int height(BTNode<E>*root)
{
	if (root == NULL)
		return 0;
	int hl = height(root->left());
	int hr = height(root->right());
	if (hl > hr)
		return ++hl;
	else
		return ++hr;
}

template<typename E>
int nodeSize(BTNode<E>*root)
{
	/*static int nodesize = 1;
	if (root == NULL)
		return 0;
	nodeSize(root->left());
	nodeSize(root->right());
	return nodesize++;*/

	if (root == NULL)
		return 0;
	return 1 + nodeSize(root->left()) + nodeSize(root->right());
}

int main()
{
	BTNode<int>*root;
	root = new BTNode<int>;
	root->setElement(10);
	root->setLeft(new BTNode<int>(4));
	root->setRight(new BTNode<int>(5));
	root->left()->setRight(new BTNode<int>(7));
	root->right()->setLeft(new BTNode<int>(9));

	root->traverse();

	preOrder(root);
	cout << endl;
	inOrder(root);
	cout << endl;
	postOrder(root);
	cout << endl;

	cout <<"height:"<< height(root) << endl;
	cout << "node size:"<<nodeSize(root) << endl;

	system("pause");
}

  輸出:

三、注意事項:

  • 用鏈式儲存二叉樹的結構性記憶體開銷十分大
  • 鑑於完全二叉樹的特點,可以用陣列來儲存完全二叉樹
  • 實際使用二叉樹時,葉節點與內部節點是否使用相同的類定義十分重要