二叉樹按照資料結構型別來劃分屬於樹結構,在樹結構中他又是比較簡單而且具有理論研究的意義的一種資料結構。有很多樹形結構都是基於二叉樹的變種,所以對二叉樹的學習與了解是很有必要的。根據筆者的經驗,在學習資料結構的過程中要深刻的體會邏輯介面與物理儲存實現的區別與聯絡。比如在之前的部落格中有講到棧和佇列的實現,棧和佇列都有基於陣列儲存方式的實現和基於鍊錶儲存形式的實現。所謂的邏輯介面就是這個資料結構具備哪些特點與性質,具備哪些抽象的能力,比如棧是乙個後進者先出的特點,普通佇列是先進者先出特點。可是這些特點與性質在具體的實現的時候可是各有不同了,如果是基於陣列儲存的棧,那內部維護的就是乙個連續的記憶體空間,所有的操作僅僅是作用在陣列的索引下標上。如果是基於鏈式儲存的棧,那麼內部就是維護了乙個單鏈表。
二叉樹是每個節點最多有兩個子樹的有序樹。通常子樹被稱作「左子樹」(left subtree)和「右子樹」(right subtree)。二叉樹常被用於實現二叉查詢樹和二叉堆。值得注意的是,二叉樹不是樹的特殊情形。在圖論中,二叉樹是乙個連通的無環圖,並且每乙個頂點的度不大於3。有根二叉樹還要滿足根結點的度不大於2。有了根結點後,每個頂點定義了唯一的根結點,和最多2個子結點。然而,沒有足夠的資訊來區分左結點和右結點。
二叉樹的儲存結構一般採用二叉鍊錶,樹中每乙個結點都有乙個資料域data還有兩個分別用於指向該節點的左右兒子結點的指標域,通過這兩個指標域建立了上下層結點的關係,這樣就可以為以後的遍歷奠定基礎了。
結點類的類宣告:
}; 文中的二叉樹採用的是前序遞迴的形式建立的,在遞迴的過程中要有乙個出口,做法是:當某個結點的指標域均為null時就說明該節點是葉子結點了,就不再往下遞迴了。#pragma once
#includeusing namespace std;
templateclass bt_node//二叉樹結點類
bt_node(t da)//有參建構函式 用於深複製等需要根據已有資料開闢空間的
~bt_node()//析構函式
templatevoid bintree::createbintree_(ifstream& in,bt_node* &subtree) //檔案流輸入過載 適用於從檔案中讀進記憶體
else
subtree = null;//把當前引數中的指標置為null 封閉子樹指標域
}}
下面是原始碼,已經注釋的很清晰了,由於遍歷和建立樹,以及求結點數目,求高度等函式都是遞迴實現的,所以實現了兩個版本,乙個是內部遞迴使用的私有的函式名後面有下劃線,對外的介面是無參的,裡面直接呼叫的是私有函式。還有關於模板函式的友元形式的宣告,在vs系列編譯器中必須加template才行。
#pragma once
#include"bintreenode.h"
#include#include #include#include//檔案流 過載輸入
using namespace std;
templateclass bintree
;/****************** 私有函式域 ******************/
templatevoid bintree::destroy_(bt_node*subtree)//刪除
//當前指標為null時 會不執行語句直接返回上一層
}templatebt_node* bintree::find_(bt_node*subtree,const t& x)const //查詢
bt_node*temp;
if((temp = find_(subtree->leftchild,x)) != null)//若當前不相等 則遞迴下去
return temp;
else
return find_(subtree->rightchild,x);
}templatebt_node* bintree::copy_(bt_node*orignnode)//複製 返回根結點指標引數(複製 結點)
templatevoid bintree::operator= (bintree&bt)
templateint bintree::height_(bt_node*subtree)//求一棵二叉樹的高度或是深度
}templateint bintree::size_(bt_node*subtree)//求一棵二叉樹的結點個數
}templatebt_node* bintree::parent_(bt_node*subtree,bt_node*current)
templatevoid bintree::preorder_(bt_node*subtree,void (* )(bt_node*))//前序遍歷
//當前指標為空則直接不執行 返回上一層
}templatevoid bintree::inorder_(bt_node*subtree,void (* )(bt_node*))//中序遍歷
}templatevoid bintree::postorder_(bt_node*subtree,void (* )(bt_node*))//後序遍歷
}templatevoid bintree::createbintree_(ifstream& in,bt_node* &subtree) //檔案流輸入過載 適用於從檔案中讀進記憶體
else
subtree = null;//把當前引數中的指標置為null 封閉子樹指標域 }}
templatevoid bintree::createbintree_(istream& in,bt_node* &subtree) //標準輸入流過載 適用於從鍵盤上讀進記憶體
if(item == endflag_value) }
templatevoid bintree::output_(ostream& out,bt_node*subtree)//輸出一棵二叉樹 假定使用前序遍歷方式
}/****************** 私有函式域 ******************/
/****************** 對外介面域 ******************/
templatebintree::bintree()
templatebintree::bintree(t value)
templatebintree::bintree(bintree&tree)//深複製函式
templatebintree::~bintree()
templatebool bintree::isempty()//判樹空
templatebt_node* & bintree::get_root()//返回樹的根結點
templatebt_node* bintree::get_parent(bt_node*current)//返回父結點 用於對外介面 只接受乙個指標引數
templatebt_node* bintree::get_leftchild(bt_node*subtree)//返回該結點的左孩子
templatebt_node* bintree::get_rightchild(bt_node*subtree)//返回該結點的右孩子
templateint bintree::get_height()//返回樹的高度或是深度 對外無參介面
templateint bintree::get_size()//返回樹的結點個數 對外無參介面
templatevoid bintree::destroy()
templatevoid bintree::preorder(void (* visit)(bt_node*))//前序遍歷 無參對外介面內部使用根結點封裝
templatevoid bintree::inorder(void (* visit)(bt_node*))//中序遍歷
templatevoid bintree::postorder(void (* visit)(bt_node*))//後序遍歷
templatevoid bintree::levelorder(void (* )(bt_node*))//按層遍歷 要用到佇列 逐層訪問類問題
}templatebt_node* bintree::find(const t &item) const//搜尋
templateifstream& operator>> (ifstream& input,bintree&tree)//友元 過載 輸入
templateistream& operator>> (istream& input,bintree&tree)
templateostream& operator<< (ostream& output,bintree&tree)//這裡的輸出是乙個全域性函式,與類無關
二叉樹詳解
一 簡介 世界上的樹有千萬種,我們這裡來學習我們資料結構中的樹,它是我們現實生活中倒置的樹。之前,我們學習的順序表,鍊錶,棧 和佇列。可以說都是我們的線性結構,也就是我們所謂的一對一的結構,可是現實生活中,我們經常碰到是我們一對多的情況。今天,我們就來研究一下這種一對多的資料結構體 樹 那麼,什麼叫...
二叉樹詳解
一 二叉樹的一些概念 二叉樹就是每個結點最多有兩個子樹的樹形儲存結構。先上圖,方便後面分析。1 滿二叉樹和完全二叉樹 上圖就是典型的二叉樹,其中左邊的圖還叫做滿二叉樹,右邊是完全二叉樹。然後我們可以得出結論,滿二叉樹一定是完全二叉樹,但是反過來就不一定。滿二叉樹的定義是除了葉子結點,其它結點左右孩子...
二叉樹詳解
樹是一種比較重要的資料結構,尤其是二叉樹。二叉樹是一種特殊的樹,在二叉樹中每個節點最多有兩個子節點,一般稱為左子節點和右子節點 或左孩子和右孩子 並且二叉樹的子樹有左右之分,其次序不能任意顛倒。本篇部落格將詳細為大家解析二叉樹。首先介紹兩個概念 滿二叉樹 在一棵二叉樹中,如果所有分支結點都有左孩子和...