C++二叉樹探究
本文將對C++二叉樹進行分析和程式碼實現。
樹
定義
樹(Tree)是n(n>=0)個結點的有限集。n=0時稱為空樹。在任意一顆非空樹中:
1)有且僅有一個特定的稱為根(Root)的結點;
2)當n>1時,其餘結點可分為m(m>0)個互不相交的有限集T1、T2、......、Tn,其中每一個集合本身又是一棵樹,並且稱為根的子樹。
此外,樹的定義還需要強調以下兩點:
1)n>0時根結點是唯一的,不可能存在多個根結點,資料結構中的樹只能有一個根結點。
2)m>0時,子樹的個數沒有限制,但它們一定是互不相交的。
結點的度
結點擁有子樹數目稱為節點的度。
結點關係
結點子樹的根結點為該結點的孩子結點
在上圖中,A為B的雙親結點,B為A的孩子結點。
同一個雙親結點的孩子結點之間互稱兄弟結點。
在上圖中,結點B與結點C互為兄弟結點。
結點層次
從根開始定義起,根為第一層,根的孩子為第二層,以此類推。
二叉樹定義
二叉樹:是n(n>=0)個結點的有限集合,該集合或者為空集(稱為空二叉樹),或者由一個根結點和兩棵互不相交的、分別稱為根結點的左子樹和右子樹的二叉樹組成。
如下圖就是一個二叉樹:
二叉樹特點
二叉樹的特點有:
- 每個結點最多兩個子樹,所以二叉樹中不存在度大於2的結點。注意不是隻有兩棵子樹,而是最多有。沒有子樹或者有一棵子樹都是可以的。
- 左子樹和右子樹是有順序的,次序布恩那個任意顛倒。
- 即使樹中的某結點只有一棵子樹,也要區分它是左子樹還是右子樹。如圖:樹1和樹2是同一棵樹,但卻是不同的二叉樹。
二叉樹具有五種基本形態:
空二叉樹;
只有一個根結點;
根結點只有左子樹;
根結點只有右子樹;
根結點既有左子樹又有右子樹。
特殊二叉樹
再來介紹一些特殊的二叉樹。
斜樹
顧名思義,斜樹一定是斜的,但是往那邊斜還是有講究的。
所有的結點都只有左子樹的二叉樹叫左斜樹,所有結點都是隻有右子樹的二叉樹叫右斜樹。兩種統稱為斜樹。
下面兩個圖分別就是左斜樹和右斜樹:
滿二叉樹
蘇東坡有詩云:人有悲歡離合,月有陰晴圓缺,此事古難全。意思就是完美是理想,不完美才是人生。
我們通常看到的例子全是左高右低、參差不齊的二叉樹,是否有完美的二叉樹呢。
在一棵二叉樹中,如果所有分支結點都存在左子樹和右子樹,並且所有的葉子結點都在同一層上,這樣的二叉樹叫做滿二叉樹。如圖
單單是每個結點都有左右子樹,不能算是滿二叉樹,還必須要所有的葉子結點都處在同一層,這樣就做到了二叉樹的平衡。因此滿二叉樹的特點有:
- 葉子只能出現在最下面一層,出現在其他層就不能達到平衡;
- 非葉子結點的度一定是2;
- 同樣深度的二叉樹中,滿二叉樹的結點個數最多,葉子樹最多。
完全二叉樹
對一棵具有n個結點的二叉樹按層序編號,如果編號為i(1<=i<=n)的結點與同樣深度的滿二叉樹中編號為i的結點在二叉樹中位置完全相同,則這棵二叉樹稱為完全二叉樹。如圖:
首先要從字面上區分,“完全”和“滿”的差異,滿二叉樹一定是完全二叉樹,完全二叉樹不一定是滿的。
注意完全二叉樹中的編號與滿二叉樹中的相同,而且編號全部連續,有斷開的就不是完全二叉樹,如下圖中的三棵樹都不是完全二叉樹。
完全二叉樹的特點:
- 葉子結點只能出現在最下面兩層;
- 最下層的葉子一定集中在左部連續位置;
- 倒數二層,若有葉子結點,一定都在右部連續位置;
- 如果結點的度為1,則該結點只有左孩子,即不存在只有右子樹的情況;
- 同樣結點數的二叉樹,完全二叉樹深度最小。
我們也得出一個判斷某二叉樹是否是完全二叉樹的方法,那就是看著樹的示意圖,心中默默給每個結點按照滿二叉樹的結構逐層順序編號,如果編號出現空擋,就說明不是完全二叉樹,否則就是。
二叉樹的性質
二叉樹性質1
在二叉樹的第i層上至多有2i-1個結點(i>=1)。
上圖中: 第1層: 1個: 21-1=20=1 第2層: 1個: 22-1=21=2 第3層: 1個: 23-1=22=4 第4層: 8個: 24-1=23=8
通過資料歸納法,很容易得出在二叉樹的第i層上最多有 2i-1個結點。
二叉樹性質2
深度為k的二叉樹最多有2k-1個結點(k>=1)。
這裡注意是2的k次冪再減1。
如果有一層,最多1=21-1個結點 如果有兩層,最多1+2=22-1個結點 如果有三層,最多1+2+4=23-1個結點 如果有四層,最多1+2+4+8=24-1個結點
通過資料歸納法的論證,可以得出如果有k層,結點數最多為2k-1。
二叉樹性質3
對任何一棵二叉樹T,如果其終端結點數為n0,度為2的結點數為n2,則n0=n2+1。
終端結點就是葉子結點,而一棵二叉樹,除了葉子結點外,剩下的就是度為1和2的結點了,設n1是度為1的結點數。則樹T的結點總數就是n=n0+n1+n2。
我們換個角度,再數一數連線線,由於根結點只有分支出去,沒有分支進入,所以分支線總數為結點總數減去1,n-1=n1+2n2,又因為n=n0+n1+n2,得出n0=n2+1 。
二叉樹性質4
具有n個結點的完全二叉樹的深度為不大於log2n的最大整數+1 。
這裡不再詳細推導。
二叉樹性質5
如果對一棵有n個結點的完全二叉樹的結點按層序編號(從第一層到最後一層,每層從左到右),對任一結點i(1<=i<=n)有:
- 如果i=1,則結點i是二叉樹的根,無雙親;如果i>1,則其雙親是結點 ⌊ i/2 ⌋ 。
- 如果2i>n,則結點i無左孩子(結點i為葉子結點);否則其左孩子是結點2i 。
- 如果2i+1>n,則結點i無右孩子;否則其右孩子是結點2i+1 。
二叉樹的儲存結構
順序儲存
二叉樹的順序儲存結構就是使用一維陣列儲存二叉樹中的結點,並且結點的儲存位置,就是陣列的下標索引。
如圖所示的一棵完全二叉樹採用順序儲存方式,如圖表示:
由圖可以看出,當二叉樹為完全二叉樹時,結點數剛好填滿陣列。
那麼當二叉樹不為完全二叉樹時,採用順序儲存形式如何呢?例如:對於上圖描述的二叉樹:
其中淺色結點表示結點不存在。那麼上圖所示的二叉樹的順序儲存結構如圖所示:
其中,∧表示陣列中此位置沒有儲存結點。此時可以發現,順序儲存結構中已經出現了空間浪費的情況。
那麼對於右斜樹極端情況對應的順序儲存結構如圖所示:
由圖可以看出,對於這種右斜樹極端情況,採用順序儲存的方式是十分浪費空間的。因此,順序儲存一般適用於完全二叉樹。
二叉樹高度
二叉樹遍歷
前序遍歷(根 左 右):G D A F E M H Z
中序遍歷(左 根 右):A D E F G H M Z
後序遍歷(左 右 根):A E F D H Z M G
層次遍歷(依次往下):G D M A F H Z E
定義
二叉樹的遍歷是指從二叉樹的根結點出發,按照某種次序依次訪問二叉樹中的所有結點,使得每個結點被訪問一次,且僅被訪問一次。
二叉樹的訪問次序可以分為四種:
前序遍歷
中序遍歷
後序遍歷
層序遍歷
前序遍歷
前序遍歷通俗的說就是從二叉樹的根結點出發,當第一次到達結點時就輸出結點資料,按照先向左在向右的方向訪問。
如圖所示二叉樹訪問如下:
從根結點出發,則第一次到達結點A,故輸出A;
繼續向左訪問,第一次訪問結點B,故輸出B;
按照同樣規則,輸出D,輸出H;
當到達葉子結點H,返回到D,此時已經是第二次到達D,故不在輸出D,進而向D右子樹訪問,D右子樹不為空,則訪問至I,第一次到達I,則輸出I;
I為葉子結點,則返回到D,D左右子樹已經訪問完畢,則返回到B,進而到B右子樹,第一次到達E,故輸出E;
向E左子樹,故輸出J;
按照同樣的訪問規則,繼續輸出C、F、G;
則圖所示二叉樹的前序遍歷輸出為:
ABDHIEJCFG
中序遍歷
中序遍歷就是從二叉樹的根結點出發,當第二次到達結點時就輸出結點資料,按照先向左在向右的方向訪問。
如圖所示二叉樹中序訪問如下:
從根結點出發,則第一次到達結點A,不輸出A,繼續向左訪問,第一次訪問結點B,不輸出B;繼續到達D,H;
到達H,H左子樹為空,則返回到H,此時第二次訪問H,故輸出H;
H右子樹為空,則返回至D,此時第二次到達D,故輸出D;
由D返回至B,第二次到達B,故輸出B;
按照同樣規則繼續訪問,輸出J、E、A、F、C、G;
則如圖所示二叉樹的中序遍歷輸出為:
HDIBJEAFCG
後序遍歷
後序遍歷就是從二叉樹的根結點出發,當第三次到達結點時就輸出結點資料,按照先向左在向右的方向訪問。
圖3.13所示二叉樹後序訪問如下:
從根結點出發,則第一次到達結點A,不輸出A,繼續向左訪問,第一次訪問結點B,不輸出B;繼續到達D,H;
到達H,H左子樹為空,則返回到H,此時第二次訪問H,不輸出H;H右子樹為空,則返回至H,此時第三次到達H,故輸出H;
由H返回至D,第二次到達D,不輸出D;
繼續訪問至I,I左右子樹均為空,故第三次訪問I時,輸出I;
返回至D,此時第三次到達D,故輸出D;
按照同樣規則繼續訪問,輸出J、E、B、F、G、C,A;
則圖3.13所示二叉樹的後序遍歷輸出為:
HIDJEBFGCA
雖然二叉樹的遍歷過程看似繁瑣,但是由於二叉樹是一種遞迴定義的結構,故採用遞迴方式遍歷二叉樹的程式碼十分簡單。
二叉樹程式碼實現
首先定義一個二叉樹,程式碼如下:
Monster m1(1,1,"刺蝟");
Monster m2(2,2,"野狼");
Monster m3(3,3,"野豬");
Monster m4(4,4,"士兵");
Monster m5(5,5,"火龍");
Monster m6(6,6,"獨角獸");
Monster m7(7,7,"江湖大盜");
TreeNode<Monster>* n1 = new TreeNode<Monster>(m1);
TreeNode<Monster>* n2 = new TreeNode<Monster>(m2);
TreeNode<Monster>* n3 = new TreeNode<Monster>(m3);
TreeNode<Monster>* n4 = new TreeNode<Monster>(m4);
TreeNode<Monster>* n5 = new TreeNode<Monster>(m5);
TreeNode<Monster>* n6 = new TreeNode<Monster>(m6);
TreeNode<Monster>* n7 = new TreeNode<Monster>(m7);
m_pRoot = n5;
n5->pLeft = n4;
n5->pRight = n6;
n4->pLeft = n1;
n1->pRight = n2;
n6->pLeft = n3;
n3->pRight = n7;
size = 7;
二叉樹的圖示如下:
這裡進入反彙編跟一下二叉樹的地址儲存,首先找到m_pRoot
的地址為3709A0
跟進去檢視,發現左子樹所在的地址為370938
,右子樹所在的地址為370A08
,這裡我繼續跟左子樹往下走
左子樹所在的地址為370800
,無右子樹所以為000000
繼續往下跟,無左子樹所以為000000
,右子樹所在的地址為370868
繼續往下跟,因為到2這個地方左子樹和右子樹都沒有了,所以地址都為000000
這裡首先實現中序遍歷,這裡通過上面的反彙編可以發現pName
即怪物名字是在序號的8個位元組之後
執行效果如下
二叉樹的圖示如下:
前序:5412637
中序:1245376
後序:2147365
前序實現
中序實現
後序實現
完整程式碼如下
// cplus二叉樹.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <Windows.h>
class Monster
{
public:
int ID;
int Level;
char Name[20];
public:
Monster(){}
Monster(int ID,int Level,char* Name)
{
this->ID = ID;
this->Level = Level;
memcpy(&this->Name,Name,strlen(Name)+1);
}
};
template<class T>
class TreeNode{
public:
T element; //當前節點儲存的資料
TreeNode<T>* pLeft; //指向左子節點的指標
TreeNode<T>* pRight; //指向右子節點的指標
TreeNode(T& ele){
//初始化Node節點
memset(&element,0,sizeof(TreeNode));
//為元素賦值
memcpy(&element,&ele,sizeof(T));
pLeft = pRight = NULL;
}
};
template<class T>
class BSortTree{
public:
BSortTree(); //建構函式
~BSortTree(); //解構函式
public:
void InOrderTraverse(TreeNode<T>* pNode); //中序遍歷
void PreOrderTraverse(TreeNode<T>* pNode); //前序遍歷
void PostOrderTraverse(TreeNode<T>* pNode); //後序遍歷
TreeNode<T>* GetRoot(); //返回根節點
int GetDepth(TreeNode<T>* pNode); //返回某個節點的高度/深度
private:
void Init();
void Clear(IN TreeNode<T>* pNode); //清理二叉樹
private:
TreeNode<T>* m_pRoot; //根結點指標
int size; //樹中元素總個數
};
template<class T>
BSortTree<T>::BSortTree()
{
Init();
}
template<class T>
BSortTree<T>::~BSortTree() //釋放所有節點空間
{
printf("The destructor has been executed!\n\n");
Clear(m_pRoot);
}
template<class T>
void BSortTree<T>::Init()
{
Monster m1(1,1,"刺蝟");
Monster m2(2,2,"野狼");
Monster m3(3,3,"野豬");
Monster m4(4,4,"士兵");
Monster m5(5,5,"火龍");
Monster m6(6,6,"獨角獸");
Monster m7(7,7,"江湖大盜");
TreeNode<Monster>* n1 = new TreeNode<Monster>(m1);
TreeNode<Monster>* n2 = new TreeNode<Monster>(m2);
TreeNode<Monster>* n3 = new TreeNode<Monster>(m3);
TreeNode<Monster>* n4 = new TreeNode<Monster>(m4);
TreeNode<Monster>* n5 = new TreeNode<Monster>(m5);
TreeNode<Monster>* n6 = new TreeNode<Monster>(m6);
TreeNode<Monster>* n7 = new TreeNode<Monster>(m7);
m_pRoot = n5;
n5->pLeft = n4;
n5->pRight = n6;
n4->pLeft = n1;
n1->pRight = n2;
n6->pLeft = n3;
n3->pRight = n7;
size = 7;
/*
5
4 6
1 3
2 7
*/
}
template<class T>
void BSortTree<T>::Clear(TreeNode<T>* pNode)
{
if( pNode != NULL )
{
Clear(pNode->pLeft);
Clear(pNode->pRight);
delete pNode;
pNode = NULL;
}
}
template<class T>
TreeNode<T>* BSortTree<T>::GetRoot()
{
return m_pRoot;
}
template<class T>
int BSortTree<T>::GetDepth(TreeNode<T>* pNode)
{
if(pNode==NULL)
{
return 0;
}
else
{
int m = GetDepth(pNode->pLeft);
int n = GetDepth(pNode->pRight);
return (m > n) ? (m+1) : (n+1);
}
}
template<class T>
void BSortTree<T>::InOrderTraverse(TreeNode<T>* pNode) //中序遍歷所有怪物,列出怪的名字(左 根 右)
{
char* pName = NULL;
if (pNode != NULL)
{
InOrderTraverse(pNode->pLeft);
pName = (char*)&pNode->element;
pName = pName + 8;
printf("Use InOrderTraverse,the value is:%d\n",pNode->element);
printf("Use InOrderTraverse,the name is:%s\n",pName);
InOrderTraverse(pNode->pRight);
}
}
template<class T>
void BSortTree<T>::PreOrderTraverse(TreeNode<T>* pNode) //前序遍歷所有怪物,列出怪的名字(根 左 右)
{
char* pName = NULL;
if (pNode != NULL)
{
pName = (char*)&pNode->element;
pName = pName + 8;
printf("Use PreOrderTraverse,the value is:%d\n",pNode->element);
printf("Use PreOrderTraverse,the name is:%s\n",pName);
PreOrderTraverse(pNode->pLeft);
PreOrderTraverse(pNode->pRight);
}
}
template<class T>
void BSortTree<T>::PostOrderTraverse(TreeNode<T>* pNode) //後序遍歷所有怪物,列出怪的名字(左 右 根)
{
char* pName = NULL;
if (pNode != NULL)
{
pName = (char*)&pNode->element;
pName = pName + 8;
PreOrderTraverse(pNode->pLeft);
PreOrderTraverse(pNode->pRight);
printf("Use PostOrderTraverse,the value is:%d\n",pNode->element);
printf("Use PostOrderTraverse,the name is:%s\n",pName);
}
}
void TestSecondtree()
{
BSortTree<Monster>* p = new BSortTree<Monster>;
p->InOrderTraverse(p->GetRoot());
p->PreOrderTraverse(p->GetRoot());
p->PostOrderTraverse(p->GetRoot());
delete p;
}
int main(int argc, char* argv[])
{
TestSecondtree();
return 0;
}
搜尋二叉樹/二叉排序樹
搜尋二叉樹/二叉排序樹的特點:
1、有很好的查詢效能
2、有很好的新增和刪除的效能
3、若左子樹不空,則左子樹上所有結點的值均小於它的根結點的值
4、若右子樹不空,則右子樹上所有結點的值均大於它的根結點的值
5、左、右子樹也分別為二叉排序樹
中序遍歷就能夠直接從小到大排列:3 5 6 7 10 12 13 15 16 18 20 23
搜尋二叉樹的刪除
情況1:葉子節點
1、刪除該節點
2、將父節點(左或者右)指標置NULL
情況2:只有一個子樹
1、刪除該節點
2、將父節點(左或者右)指標指向子樹
情況3:左右子樹都有
1、用右子樹最小的節點取代源節點
2、再遞迴刪除最小節點
搜尋二叉樹程式碼實現
寫於2021.6.15 22.22
明天歐洲盃,先溜了,德國打法國,法國沖沖衝!
1-0 小勝,但是沒看到好多進球有點可惜
首先測試一下輸出情況,no problem
完整程式碼如下主要是遍歷的思想
// cplus搜尋二叉樹.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <Windows.h>
#define SUCCESS 1 // 執行成功
#define ERROR -1 // 執行失敗
template<class T>
class TreeNode{
public:
T element; //當前節點儲存的資料
TreeNode<T>* pLeft; //指向左子節點的指標
TreeNode<T>* pRight; //指向右子節點的指標
TreeNode<T>* pParent; //指向父結點的指標
TreeNode(T& ele){
//初始化Node節點
memset(&element,0,sizeof(TreeNode));
//為元素賦值
memcpy(&element,&ele,sizeof(T));
pLeft = pRight = pParent = NULL;
}
//過載== 比較兩結點是否相等
bool operator==(TreeNode<T>* node){
return node->element == element ? true : false;
}
};
template<class T>
class BSortTree{
public:
BSortTree();
~BSortTree();
public:
bool IsEmpty();
DWORD Insert(T element);
void Delete(T element);
TreeNode<T>* Search(T element);
void InOrderTraverse(TreeNode<T>* pNode);
void PreOrderTraverse(TreeNode<T>* pNode);
void PostOrderTraverse(TreeNode<T>* pNode);
private:
TreeNode<T>* GetMaxNode(TreeNode<T>* pNode);
TreeNode<T>* GetMinNode(TreeNode<T>* pNode);
TreeNode<T>* SearchNode(TreeNode<T>* pNode,T element);
DWORD InsertNode(T element, TreeNode<T>* pNode);
TreeNode<T>* DeleteNode(T element, TreeNode<T>* pNode);
void Clear(TreeNode<T>* pNode);
private:
TreeNode<T>* m_pRoot;
int size;
};
template<class T>
BSortTree<T>::BSortTree()
{
m_pRoot = NULL;
size = 0;
}
template<class T>
BSortTree<T>::~BSortTree(){
Clear(m_pRoot);
}
template<class T>
DWORD BSortTree<T>::Insert(T element)
{
//如果根節點為空
if ( !m_pRoot )
{
m_pRoot = new TreeNode<T>(element);
size++;
return SUCCESS;
}
//如果根節點不為空
return InsertNode(element, m_pRoot);
}
template<class T>
DWORD BSortTree<T>::InsertNode(T element, TreeNode<T>* pNode)
{
//將元素封裝到節點中
TreeNode<T>* pNewNode = new TreeNode<T>(element);
//如果element == 當前節點 直接返回
if(element == pNode->element)
{
return SUCCESS;
}
//如果pNode的左子節點為NULL 並且element < 當前節點
if(pNode->pLeft == NULL && element < pNode->element)
{
pNode->pLeft = pNewNode;
pNewNode->pParent = pNode;
size++;
return SUCCESS;
}
//如果pNode的右子節點為NULL 並且element > 當前節點
if(pNode->pRight == NULL && element > pNode->element){
pNode->pRight = pNewNode;
pNewNode->pParent = pNode;
size++;
return SUCCESS;
}
//如果element<當前節點 且當前節點的左子樹不為空
if(element < pNode->element)
{
InsertNode(element,pNode->pLeft);
}
else
{
InsertNode(element,pNode->pRight);
}
return SUCCESS;
}
template<class T>
void BSortTree<T>::Clear(TreeNode<T>* pNode)
{
if(pNode!=NULL)
{
Clear(pNode->pLeft);
Clear(pNode->pRight);
delete pNode;
pNode=NULL;
}
}
template<class T>
bool BSortTree<T>::IsEmpty()
{
return size==0 ? true : false;
}
template<class T>
TreeNode<T>* BSortTree<T>::Search(T element)
{
return SearchNode(m_pRoot, element);
}
template<class T>
TreeNode<T>* BSortTree<T>::SearchNode(TreeNode<T>* pNode,T element)
{
if(pNode == NULL) //如果節點為NULL
{
return NULL;
}
else if(element == pNode->element) //如果相等
{
return pNode;
}
else if(element < pNode->element) //如果比節點的元素小 向左找
{
return SearchNode(pNode->pLeft,element);
}
else //如果比節點的元素大 向右找
{
return SearchNode(pNode->pRight,element);
}
}
template<class T>
void BSortTree<T>::Delete(T element)
{
if (! m_pRoot == NULL) //指標為空則二叉樹沒有成員
{
printf("No member is in the binary tree and cannot be deleted!\n");
}
else //呼叫DeleteNode()方法刪除節點
{
TreeNode<T>* ptemp = SearchNode(m_pRoot , element);
DeleteNode(element, ptemp);
}
}
template<class T>
TreeNode<T>* BSortTree<T>::DeleteNode(T element,TreeNode<T>* pNode)
{
if (!pNode->pLeft && !pNode->pRight) //無左子樹也無右子樹
{
if (pNode->element < pNode->pParent->element)
{
pNode->pParent->pLeft = NULL;
}
else
{
pNode->pParent->pRight = NULL;
}
delete pNode;
}
else if (pNode->pLeft && !pNode->pRight) //有左子樹無右子樹
{
if (pNode->element < pNode->pParent->element)
{
pNode->pParent->pLeft = pNode->pLeft;
pNode->pLeft->pParent = pNode->pParent;
}
else
{
pNode->pParent->pRight = pNode->pLeft;
pNode->pLeft->pParent = pNode->pParent;
}
delete pNode;
}
else if (!pNode->pLeft && pNode->pRight) //無左子樹有右子樹
{
if (pNode->elment < pNode->pParent->element)
{
pNode->pParent->pLeft = pNode->pRight;
pNode->pRight->pParent = pNode->pParent;
}
else
{
pNode->pParent->pRight = pNode->p Right;
pNode->pRight->pParent = pNode->pParent;
}
delete pNode;
}
else (pNode->pLeft && pNode->pRight) //左右子樹都有
{
TreeNode<T>* pRightMinNode = GetRightMinNode(pNode->pRight);
pNode->element = pRightMinNode->element;
DeleteNode(pRightMinNode->element, pRightMinNode);
}
return NULL;
}
//測試程式碼:
void TestInsert()
{
//12 8 5 9 17 15 13
/*
12
8 17
5 9 15
13
*/
BSortTree<int> tree;
tree.Insert(12);
tree.Insert(8);
tree.Insert(5);
tree.Insert(9);
tree.Insert(17);
tree.Insert(15);
tree.Insert(13);
}
void TestSearch()
{
//12 8 5 9 17 15 13
BSortTree<int> tree;
tree.Insert(12);
tree.Insert(8);
tree.Insert(5);
tree.Insert(9);
tree.Insert(17);
tree.Insert(15);
tree.Insert(13);
TreeNode<int>* p = tree.Search(9);
TreeNode<int>* q = tree.Search(17);
printf("The search value is:%d\nThe address of search value is:%x\n",p->element,p);
printf("The search value is:%d\nThe address of search value is:%x\n",q->element,q);
}
int main(int argc, char* argv[])
{
TestInsert();
TestSearch();
return 0;
}