博主介紹:?全網(wǎng)粉絲喜愛+、前后端領(lǐng)域優(yōu)質(zhì)創(chuàng)作者、本質(zhì)互聯(lián)網(wǎng)精神、堅(jiān)持優(yōu)質(zhì)作品共享、掘金/騰訊云/阿里云等平臺優(yōu)質(zhì)作者、擅長前后端項(xiàng)目開發(fā)和畢業(yè)項(xiàng)目實(shí)戰(zhàn)?有需要可以聯(lián)系作者我哦!
??附上相關(guān)C語言版源碼講解??
???? 精彩專欄推薦訂閱???? 不然下次找不到喲
目錄
一、二叉樹定義(特點(diǎn)+結(jié)構(gòu))
二叉樹算法性質(zhì):
二、算法實(shí)現(xiàn)(完整代碼)
三、算法總結(jié)
二叉樹的優(yōu)點(diǎn):
?二叉樹的缺點(diǎn):
二叉樹的應(yīng)用:
小結(jié)
大家點(diǎn)贊、收藏、關(guān)注、評論啦 !
謝謝哦!如果不懂,歡迎大家下方討論學(xué)習(xí)哦。
一、二叉樹定義(特點(diǎn)+結(jié)構(gòu))
二叉樹是一種樹形結(jié)構(gòu),每個節(jié)點(diǎn)最多有兩個子節(jié)點(diǎn),分別稱為左子節(jié)點(diǎn)和右子節(jié)點(diǎn)。二叉樹具有以下定義和特點(diǎn):
1. 節(jié)點(diǎn):二叉樹是由節(jié)點(diǎn)構(gòu)成的集合。每個節(jié)點(diǎn)包含三個基本信息:
? ?- 數(shù)據(jù)元素(或稱為節(jié)點(diǎn)值)。
? ?- 指向左子節(jié)點(diǎn)的指針/引用。
? ?- 指向右子節(jié)點(diǎn)的指針/引用。
2. 根節(jié)點(diǎn):?二叉樹中的一個節(jié)點(diǎn)被稱為根節(jié)點(diǎn),它是整個樹的起始節(jié)點(diǎn)。一棵二叉樹只有一個根節(jié)點(diǎn)。
3. 葉子節(jié)點(diǎn):沒有子節(jié)點(diǎn)的節(jié)點(diǎn)被稱為葉子節(jié)點(diǎn)(或葉節(jié)點(diǎn))。
4. 父節(jié)點(diǎn)和子節(jié)點(diǎn):?每個節(jié)點(diǎn)都有一個父節(jié)點(diǎn),除了根節(jié)點(diǎn)。父節(jié)點(diǎn)指向它的子節(jié)點(diǎn)。
5. 深度:一個節(jié)點(diǎn)的深度是從根節(jié)點(diǎn)到該節(jié)點(diǎn)的唯一路徑的邊的數(shù)量。根節(jié)點(diǎn)的深度為0。
6. 高度/深度:?一棵二叉樹的高度(或深度)是樹中任意節(jié)點(diǎn)的最大深度。
7. 子樹:二叉樹中的任意節(jié)點(diǎn)和它的所有子孫節(jié)點(diǎn)組成的集合被稱為子樹。
8. 二叉搜索樹(BST):在二叉搜索樹中,每個節(jié)點(diǎn)的左子樹中的節(jié)點(diǎn)值都小于該節(jié)點(diǎn)的值,而右子樹中的節(jié)點(diǎn)值都大于該節(jié)點(diǎn)的值。
9. 滿二叉樹:如果一棵深度為k,且有2^k - 1個節(jié)點(diǎn)的二叉樹被稱為滿二叉樹。
10. 完全二叉樹:對于一棵深度為k的二叉樹,除了最后一層外,其它各層的節(jié)點(diǎn)數(shù)都達(dá)到最大值,且最后一層的節(jié)點(diǎn)都集中在左邊,被稱為完全二叉樹。
二叉樹的定義為:
struct TreeNode {
int val; // 節(jié)點(diǎn)值
TreeNode *left; // 左子節(jié)點(diǎn)指針
TreeNode *right; // 右子節(jié)點(diǎn)指針
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
上述定義為C++中使用類實(shí)現(xiàn)的二叉樹節(jié)點(diǎn)定義,包含節(jié)點(diǎn)值、左子節(jié)點(diǎn)指針和右子節(jié)點(diǎn)指針。
二叉樹算法性質(zhì):
你提到的這些性質(zhì)描述了二叉搜索樹(Binary Search Tree,BST)的一些重要特征。讓我們逐一解釋這些性質(zhì):
1. 將任何一個點(diǎn)看作Root節(jié)點(diǎn),則這個點(diǎn)的左子樹也是 Binary Search Tree:這表示二叉搜索樹中每個節(jié)點(diǎn)的左子樹都滿足二叉搜索樹的性質(zhì),即左子樹上的節(jié)點(diǎn)值小于當(dāng)前節(jié)點(diǎn)的值。
2. 將任何一個點(diǎn)看作Root節(jié)點(diǎn),則這個點(diǎn)的右子樹也是 Binary Search Tree:類似地,這表明每個節(jié)點(diǎn)的右子樹都是一個二叉搜索樹,右子樹上的節(jié)點(diǎn)值大于當(dāng)前節(jié)點(diǎn)的值。
3. Binary Search Tree中的最小節(jié)點(diǎn),一定是整棵樹中最左下的葉子節(jié)點(diǎn):這是因?yàn)樽钚」?jié)點(diǎn)不會有左子節(jié)點(diǎn),只能一直沿著左子樹往下走,直到葉子節(jié)點(diǎn)。
4. Binary Search Tree中的最大節(jié)點(diǎn),一定是整棵樹中最右下的葉子節(jié)點(diǎn):同樣,最大節(jié)點(diǎn)不會有右子節(jié)點(diǎn),只能一直沿著右子樹往下走,直到葉子節(jié)點(diǎn)。
這些性質(zhì)是二叉搜索樹在節(jié)點(diǎn)排列和結(jié)構(gòu)上的特點(diǎn),它們使得在二叉搜索樹上執(zhí)行搜索、插入和刪除等操作更加高效。通過遵循這些性質(zhì),可以確保在整個樹結(jié)構(gòu)中維持有序性,使得二叉搜索樹成為一種常用的數(shù)據(jù)結(jié)構(gòu)。
二、算法實(shí)現(xiàn)(完整代碼)
通過二叉樹實(shí)現(xiàn)A、B、C、D的簡單應(yīng)用
#include<iostream>
using namespace std;
typedef char DataType;
struct BiNode
{
DataType data;
BiNode *lchild,*rchild;
};
//(1)假設(shè)二叉樹采用鏈接存儲方式存儲,分別編寫一個二叉樹先序遍歷的遞歸
//算法和非遞歸算法。
class BiTree
{
public:
BiTree(){root=Create(root);}//構(gòu)造函數(shù),建立一顆二叉樹
~BiTree(){Release(root);}//析構(gòu)函數(shù),釋放各個節(jié)點(diǎn)的存儲空間
void Preorder(){Preorder(root);}//前序遍歷二叉樹
void Inorder(){Inorder(root);}//中序遍歷二叉樹
void Postorder(){Postorder(root);}//后序遍歷二叉樹
void Levelorder(){Levelorder(root);};//層序遍歷二叉樹
private:
BiNode *root;//指向根節(jié)點(diǎn)的頭指針
BiNode *Create(BiNode *bt);//構(gòu)造函數(shù)調(diào)用
void Release(BiNode *bt);//析構(gòu)函數(shù)調(diào)用
void Preorder(BiNode *bt);//前序遍歷函數(shù)調(diào)用
void Inorder(BiNode *bt);//中序遍歷函數(shù)調(diào)用
void Postorder(BiNode *bt);//后序遍歷函數(shù)調(diào)用
void Levelorder(BiNode *bt);//層序遍歷函數(shù)調(diào)用
};
//前序遍歷
void BiTree::Preorder(BiNode *bt)
{
if(bt==NULL)return;//遞歸調(diào)用的結(jié)束條件
else{
cout<<bt->data<<" ";//訪問根節(jié)點(diǎn)bt的數(shù)據(jù)域
Preorder(bt->lchild);//前序遞歸遍歷bt的左子樹
Preorder(bt->rchild);//前序遞歸遍歷bt的右子樹
}
}
//中序遍歷
void BiTree::Inorder(BiNode *bt)
{
if(bt==NULL)return;//遞歸調(diào)用的結(jié)束條件
else{
Inorder(bt->lchild);//中序遞歸遍歷bt的左子樹
cout<<bt->data<<" ";//訪問根節(jié)點(diǎn)的數(shù)據(jù)域
Inorder(bt->rchild);//中序遞歸遍歷bt的右子樹
}
}
//后序遍歷
void BiTree::Postorder(BiNode *bt)
{
if(bt==NULL)return;//遞歸調(diào)用的結(jié)束條件
else{
Postorder(bt->lchild);//后序遞歸遍歷bt的左子樹
Postorder(bt->rchild);//后序遞歸遍歷bt的右子樹
cout<<bt->data<<" ";//訪問根節(jié)點(diǎn)bt的數(shù)據(jù)域
}
}
//層序遍歷
void BiTree::Levelorder(BiNode *bt){
BiNode *Q[100],*q=NULL;
int front=-1,rear=-1;//隊(duì)列初始化
if(root == NULL) return;//二叉樹為空,算法結(jié)束
Q[++rear]=root;//根指針入隊(duì)
while(front!=rear){//當(dāng)隊(duì)列非空時
q=Q[++front];//出隊(duì)
cout<<q->data<<" ";
if(q->lchild!=NULL) Q[++rear]=q->lchild;
if(q->rchild!=NULL) Q[++rear]=q->rchild;
}
}
//創(chuàng)建二叉樹
BiNode *BiTree::Create(BiNode *bt)
{
static int i=0;
char ch;
string str="AB#D##C##";
ch=str[i++];
if(ch=='#')bt=NULL;//建立一棵空樹
else {
bt=new BiNode;bt->data=ch;//生成一個結(jié)點(diǎn),數(shù)據(jù)域?yàn)閏h
bt->lchild=Create(bt->lchild);//遞歸建立左子樹
bt->rchild=Create(bt->rchild);//遞歸建立右子樹
}
return bt;
}
//銷毀二叉樹
void BiTree::Release(BiNode *bt)
{
if(bt!=NULL){
Release(bt->lchild);
Release(bt->rchild);
delete bt;
}
}
int main()
{
cout<<"創(chuàng)建一棵二叉樹"<<endl;
BiTree T;//創(chuàng)建一顆二叉樹
cout<<"---層序遍歷---"<<endl;//A B C D
T.Levelorder();
cout<<endl;
cout<<"---前序遍歷---"<<endl;//A B D C
T.Preorder();
cout<<endl;
cout<<"---中序遍歷---"<<endl;//B D A C
T.Inorder();
cout<<endl;
cout<<"---后序遍歷---"<<endl;//D B C A
T.Postorder();
cout<<endl;
return 0;
}
執(zhí)行結(jié)果:
序存儲的完全二叉樹遞歸先序遍歷算法描述(C++)如下:
//完全二叉樹的順序存儲結(jié)構(gòu)
#include <iostream>
#include <string.h>
#define MaxSize 100
using namespace std;
typedef char DataType;
class Tree{
public:
Tree(string str);//構(gòu)造函數(shù)
void createTree();//創(chuàng)建二叉樹
void seqPreorder(int i);//先序遍歷二叉樹
void seqInorder(int i);//中序遍歷二叉樹
void seqPostorder(int i);//后序遍歷二叉樹
private:
DataType node[MaxSize];//結(jié)點(diǎn)中的數(shù)據(jù)元素
int num=0;//二叉樹結(jié)點(diǎn)個數(shù)
string str;
};
Tree::Tree(string str){
this->str = str;
}
void Tree::createTree(){
for(int i = 1;i < str.length()+1 ;i++){
node[i]=str[i-1];
num++;
}
node[0] = (char)num;
}
//順序存儲的完全二叉樹遞歸先序遍歷算法描述(C++)如下:
void Tree::seqPreorder(int i){
if(i==0)//遞歸調(diào)用的結(jié)束條件
return;
else{
cout<<" "<<(char)node[i];//輸出根結(jié)點(diǎn)
if(2*i<=(char)node[0])
seqPreorder(2*i);//先序遍歷i的左子樹
else
seqPreorder(0);
if(2*i+1<=(char)node[0])
seqPreorder(2*i+1);//先序遍歷i的右子樹
else
seqPreorder(0);
}
}
//順序存儲的完全二叉樹遞歸中序遍歷算法描述(C++)如下:
void Tree::seqInorder(int i){
if(i==0)//遞歸調(diào)用的結(jié)束條件
return;
else{
if(2*i<=(char)node[0])
seqInorder(2*i);//中序遍歷i的左子樹
else
seqInorder(0);
cout<<" "<<(char)node[i];//輸出根結(jié)點(diǎn)
if(2*i+1<=(char)node[0])
seqInorder(2*i+1);//中序遍歷i的右子樹
else
seqInorder(0);
}
}
//順序存儲的完全二叉樹遞歸后序遍歷算法描述(C++)如下:
void Tree::seqPostorder(int i){
if(i==0)//遞歸調(diào)用的結(jié)束條件
return;
else{
if(2*i<=(char)node[0])
seqPostorder(2*i);//后序遍歷i的左子樹
else
seqPostorder(0);
if(2*i+1<=(char)node[0])
seqPostorder(2*i+1);//后序遍歷i的右子樹
else
seqPostorder(0);
cout<<" "<<(char)node[i];//輸出根結(jié)點(diǎn)
}
}
// (2)一棵完全二叉樹以順序方式存儲,設(shè)計(jì)一個遞歸算法,對該完全二叉樹進(jìn)
//行中序遍歷。
int main(){
string str = "ABCDEFGHIJ";
Tree T(str);//定義對象變量bus
cout<<"按層序編號的順序存儲所有結(jié)點(diǎn):"<<str<<endl;
T.createTree();
cout<<"順序存儲的完全二叉樹遞歸前序遞歸遍歷:"<<endl;
T.seqPreorder(1);
cout<<endl;
cout<<"順序存儲的完全二叉樹遞歸中序遞歸遍歷:"<<endl;
T.seqInorder(1);
cout<<endl;
cout<<"順序存儲的完全二叉樹遞歸后序遞歸遍歷:"<<endl;
T.seqPostorder(1);
cout<<endl;
return 0;
}
三、算法總結(jié)
二叉樹的優(yōu)點(diǎn):
1. 快速查找:?在二叉搜索樹(BST)中,查找某個元素的時間復(fù)雜度是O(log n),這使得二叉樹在查找操作上非常高效。
2. 有序性:BST保持元素的有序性,對于某些應(yīng)用場景,如快速查找最小值、最大值或在某一范圍內(nèi)的值,二叉樹非常有用。
3. 容易插入和刪除:在BST中,插入和刪除操作相對容易,不需要像其他數(shù)據(jù)結(jié)構(gòu)一樣頻繁地移動元素。
4. 中序遍歷:通過中序遍歷二叉搜索樹,可以得到有序的元素序列,這對于某些應(yīng)用(如構(gòu)建有序列表)很方便。
?二叉樹的缺點(diǎn):
1. 平衡性:如果不平衡,二叉搜索樹的性能可能下降為線性級別,而不再是對數(shù)級別。因此,需要采取額外的措施來保持樹的平衡,如 AVL 樹或紅黑樹。
2. 對數(shù)據(jù)分布敏感:?對于某些特定的數(shù)據(jù)分布,比如按順序插入的數(shù)據(jù),可能導(dǎo)致二叉搜索樹退化成鏈表,性能下降。
二叉樹的應(yīng)用:
1. 數(shù)據(jù)庫索引:在數(shù)據(jù)庫中,二叉搜索樹被廣泛應(yīng)用于構(gòu)建索引結(jié)構(gòu),以加速數(shù)據(jù)的檢索。
2. 表達(dá)式解析:二叉樹可用于構(gòu)建表達(dá)式樹,用于解析和求解數(shù)學(xué)表達(dá)式。
3. 哈夫曼編碼:二叉樹用于構(gòu)建哈夫曼樹,實(shí)現(xiàn)有效的數(shù)據(jù)壓縮算法。
4. 文件系統(tǒng):在文件系統(tǒng)的目錄結(jié)構(gòu)中,可以使用二叉樹來組織和管理文件。
5. 網(wǎng)絡(luò)路由:用于構(gòu)建路由表,支持快速而有效的網(wǎng)絡(luò)數(shù)據(jù)包路由。
6. 編譯器設(shè)計(jì):?語法分析階段通常使用二叉樹來構(gòu)建語法樹,以便后續(xù)的編譯步驟。
7. 游戲開發(fā):在游戲開發(fā)中,二叉樹可以用于實(shí)現(xiàn)場景圖、動畫系統(tǒng)等。
8. 排序算法:一些排序算法,如快速排序,就是通過構(gòu)建和操作二叉樹來實(shí)現(xiàn)的。文章來源:http://www.zghlxwxcb.cn/news/detail-819029.html
總體而言,二叉樹在計(jì)算機(jī)科學(xué)領(lǐng)域的應(yīng)用非常廣泛,它的特性使得它適用于多種數(shù)據(jù)管理和搜索場景。在實(shí)際應(yīng)用中,需要根據(jù)具體情況選擇合適的二叉樹變體以及適當(dāng)?shù)钠胶獠呗浴?span toymoban-style="hidden">文章來源地址http://www.zghlxwxcb.cn/news/detail-819029.html
大家點(diǎn)贊、收藏、關(guān)注、評論啦 !
謝謝哦!如果不懂,歡迎大家下方討論學(xué)習(xí)哦。
到了這里,關(guān)于【數(shù)據(jù)結(jié)構(gòu)】二叉樹算法講解(定義+算法原理+源碼)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!