二叉樹的概念
二叉樹是一棵每個節點都不能有多於兩個兒子的樹
有N個結點的完全二叉樹的深度:
公式:K =「log2n」+1
證明:可用數學歸納法。
當n=1=2^1-1時顯然。
假設當n<=2^k-1時具有n個結點的完全二叉樹的深度爲「log2n」+1,則
當n=2^k(以及2^k+1,…,2^(k+1)-1)時,由歸納假設知前2^k-1個結點構成深度爲「log2n」+1的樹,再由完全二叉樹的定義知剩餘的1(或2,…,2^k)個結點均填在第「log2n」+2層上(作爲“葉子”),故深度剛好增加了1。
故n<=2^(k+1)-1時命題成立。證畢。
(首先最好能先從直觀上理解:完全二叉樹中:
第1層有1個結點;
第2層有2個結點;
第3層有4個結點;
……
第k層有2^(k-1)個結點;(前k層共有(2^k)-1個結點,故前面深度剛好是「log2(2^k-1)」+1=k-1+1=k)
第k+1層是剩餘的結點。
二叉樹的平均深度爲
二叉樹的實現
因爲一個二叉樹結點最多有兩個兒子,所以可以直接鏈接到它們。樹節點的聲明在結構上類似於雙向鏈表的聲明。在聲明中,一個結點就是由element的信息加上兩個到其他結點的引用(
struct BinaryNode
{
Object element; //data in the node
BinaryNode *left; //Left child
BinaryNode *right; //Right child
}
二叉樹的創建
#include<iostream>
using namespace std;
typedef struct node
{
struct node *leftChild;
struct node *rightChild;
char data;
}BiTreeNode ,*BiTree;
//————————建立二叉樹——————————
void createBitree(BiTree &T)
{
char c;
cin>>c;
if('#'==c)
T==NULL;
else
{
T=new BiTreeNode;
T->data=c;
createBitree(T->leftChild);
createBitree(T->rightChild);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
BiTree T;
int numNode;
createBitree(T);
cout<<"二叉樹建立完成"<<endl;
system("pause");
return 0;
}
二叉樹常見問題
題目參照:http://blog.csdn.net/luckyxiaoqiang/article/details/7518888
1)遍歷:前序,中序,後序
2)結點個數:
遞歸解法:
(1)如果二叉樹爲空,節點個數爲0
(2)如果二叉樹不爲空,二叉樹節點個數 = 左子樹節點個數 + 右子樹節點個數 + 1
3) 求二叉樹的深度
遞歸解法:
(1)如果二叉樹爲空,二叉樹的深度爲0
(2)如果二叉樹不爲空,二叉樹的深度 = max(左子樹深度, 右子樹深度) + 1
4)分層遍歷二叉樹(按層次從上往下,從左往右)
相當於廣度優先搜索,使用隊列實現。隊列初始化,將根節點壓入隊列。當隊列不爲空,進行如下操作:彈出一個節點,訪問,若左子節點或右子節點不爲空,將其壓入隊列。
常見問題的程序實現
// three_order_map.cpp : 定義控制檯應用程序的入口點。
//
#include"stdafx.h"
#include<iostream>
#include<queue>
#define N 7
using namespace std;
typedef struct node
{
struct node *leftChild;
struct node *rightChild;
int data;
}BiTreeNode, *BiTree;
BiTreeNode *createNode(int i)
{
BiTreeNode * q = new BiTreeNode;
q->leftChild = NULL;
q->rightChild = NULL;
q->data = i; //1,2,3,4,5,6也可以自己輸入
return q;
}
BiTree createBiTree()
{
BiTreeNode *p[N] = {NULL};
int i;
for(i = 0; i < N; i++)
{
p[i] = createNode(i + 1);
cout<<p[i]->data<<endl;
}
for(i = 0; i < N/2; i++)
{
p[i]->leftChild = p[i * 2 + 1];
p[i]->rightChild = p[i * 2 + 2];
}
return p[0];
}
int visit(BiTree T)
{
return T->data;
}
// 先序遍歷
void preOrderTraverse(BiTree T)
{
if(T)
{
cout << visit(T) << " ";
preOrderTraverse(T->leftChild);
preOrderTraverse(T->rightChild);
}
}
// 中序遍歷
void inOrderTraverse(BiTree T)
{
if(T)
{
inOrderTraverse(T->leftChild);
cout << visit(T) << " ";
inOrderTraverse(T->rightChild);
}
}
// 後序遍歷
void postOrderTraverse(BiTree T)
{
if(T)
{
postOrderTraverse(T->leftChild);
postOrderTraverse(T->rightChild);
cout << visit(T) << " ";
}
}
//求二叉樹中的結點個數
int GetNodeNum(BiTreeNode * pRoot)
{
if(pRoot == NULL) // 遞歸出口
return 0;
return GetNodeNum(pRoot->leftChild) + GetNodeNum(pRoot->rightChild) + 1;
}
//求二叉樹的深度
int GetDepth(BiTreeNode * pRoot)
{
if(pRoot == NULL) // 遞歸出口
return 0;
int depthLeft = GetDepth(pRoot->leftChild);
int depthRight = GetDepth(pRoot->rightChild);
return depthLeft > depthRight ? (depthLeft + 1) : (depthRight + 1);
}
//分層遍歷二叉樹
void LevelTraverse(BiTreeNode * pRoot)
{
if(pRoot == NULL)
return;
queue<BiTreeNode *> q;
q.push(pRoot);
while(!q.empty())
{
BiTreeNode * pNode = q.front();
q.pop();
cout<<visit(pNode); // 訪問節點
if(pNode->leftChild != NULL)
q.push(pNode->leftChild);
if(pNode->rightChild != NULL)
q.push(pNode->rightChild);
}
return;
}
int main()
{
int num;
BiTree T = createBiTree(); //根節點
cout << "先序遍歷:" << endl;
preOrderTraverse(T);
cout << endl << endl;
cout << "中序遍歷:" << endl;
inOrderTraverse(T);
cout << endl << endl;
cout << "後序遍歷:" << endl;
postOrderTraverse(T);
cout << endl << endl;
num=GetNodeNum(T);
cout<<"結點個數爲 "<<num<<endl;
num=GetDepth(T);
cout<<"樹的深度爲 "<<num<<endl;
cout<<"層次遍歷的結果爲:";
LevelTraverse(T);
cout<<endl;
system("pause");
return 0;
}
由於博主的學識有限,難免會出現錯誤,歡迎大家在評論區批評,指正,交流,也歡迎大家對博文的內容上的繼續補充