資料結構——二叉樹:基本二叉樹(C++)
阿新 • • 發佈:2018-12-24
內容概要:
- 二叉樹相關概念
- 簡單二叉樹模板類的實現:二叉樹的遍歷、計算高度、計算節點數目
- 注意事項
一、二叉樹相關概念:
第一部分:
- 節點(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個節點
- 完全二叉樹(complete binary tree):從二叉樹的根節點起,每一層從左到右依次填充
第二部分:
- 非空滿二叉樹的葉節點數等於其內部節點數加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");
}
輸出:
三、注意事項:
- 用鏈式儲存二叉樹的結構性記憶體開銷十分大
- 鑑於完全二叉樹的特點,可以用陣列來儲存完全二叉樹
- 實際使用二叉樹時,葉節點與內部節點是否使用相同的類定義十分重要