當前位置:首頁 » 操作系統 » 二叉樹與演算法

二叉樹與演算法

發布時間: 2022-07-03 19:58:38

『壹』 二叉樹 演算法

原因就在於Status CreatBitTree(BitTree e) 這個函數的參數BitTree e,既然e是參數,因此你在函數體內用e=NULL; 及e=(BitTree)malloc(sizeof(BitNode)); 來給e賦值都是沒有用的,賦值不會返回給調用處。修改的話改成引用就可以了。也就是把Status CreatBitTree(BitTree e) 這一行改成Status CreatBitTree(BitTree &e) 就行了。

還有:二叉樹演算法遞歸中序輸入是abc##de#g##f### (你這應該是前序輸入吧?)

『貳』 求二叉樹的基本演算法和各種遍歷演算法

#include<iostream.h>
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef char TElemType;
typedef int Status;
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
Status CreateBiTree(BiTree &T) //按先序次序輸入二叉樹中結點的值,構造二叉樹鏈表
{
char ch;
ch=getchar();
if(ch==' ')
T=NULL;
else
{
if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))
exit(OVERFLOW);
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
return OK;
}
Status PreOrder(BiTree T) //先序遍歷的遞歸演算法
{
if(T)
{
cout<<T->data;
PreOrder(T->lchild);
PreOrder(T->rchild);
}
return OK;
}
Status InOrder(BiTree T) //中序遍歷的遞歸演算法
{
if(T)
{
InOrder(T->lchild);
cout<<T->data;
InOrder(T->rchild);
}
return OK;
}
Status PostOrder(BiTree T) //後續遍歷的遞歸函數
{
if(T)
{
PostOrder(T->lchild);
PostOrder(T->rchild);
cout<<T->data;
}
return OK;
}
Status BiTreeLevelOrder(BiTree T) //層序遍歷的非遞歸函數
{
int front=0,rear=0;
BiTree p,Q[20];
if(T)
{
rear++;
Q[rear]=T;
}
while(front!=rear)
{
front++;
p=Q[front];
cout<<p->data;
if(p->lchild)
{
rear++;
Q[rear]=p->lchild;
}
if(p->rchild)
{
rear++;
Q[rear]=p->rchild;
}
}
return OK;
}
Status BiTreeNodeSum(BiTree T) //計算二叉樹的結點數
{

if(T==NULL)
return 0;
else
return 1+BiTreeNodeSum(T->lchild)+BiTreeNodeSum(T->rchild);
}
Status BiTreeLeafSum(BiTree T) //計算二叉樹的葉子結點數
{
if(T==NULL)
return 0;
else
if(T->lchild==NULL&&T->rchild==NULL)
return 1;
else
return BiTreeLeafSum(T->lchild)+BiTreeLeafSum(T->rchild);
}
Status BiTreeDeep(BiTree T) //計算二叉樹的深度
{
if(T==NULL)
return 0;
else
return (BiTreeDeep(T->lchild)>BiTreeDeep(T->rchild))?(BiTreeDeep(T->lchild)+1):(BiTreeDeep(T->rchild)+1);
}

void main() //主函數
{
BiTree T;
cout<<"input Bitree char:"<<endl;
CreateBiTree(T);
cout<<"先序遍歷為:"<<endl;
PreOrder(T);
cout<<endl;
cout<<"中序遍歷為:"<<endl;
InOrder(T);
cout<<endl;
cout<<"後序遍歷為:"<<endl;
PostOrder(T);
cout<<endl;
cout<<"層序遍歷為:"<<endl;
BiTreeLevelOrder(T);
cout<<endl;
BiTreeNodeSum(T);
cout<<"二叉樹的結點數:"<<BiTreeNodeSum(T)<<endl;
BiTreeLeafSum(T);
cout<<"二叉樹的葉子結點數為:"<<BiTreeLeafSum(T)<<endl;
BiTreeDeep(T);
cout<<"二叉樹的深度為:"<<BiTreeDeep(T)<<endl;
}

『叄』 二叉樹結點的演算法

一個結點的度是指該結點的子樹個數。
度為1就是指只有1個子樹(左子樹或者右子樹)。
度為2的結點個數=葉結點個數-1=69
該二叉樹的總結點數=70+80+69=219

『肆』 二叉樹演算法有哪些應用場景

二叉樹常被用於實現二叉查找樹和二叉堆。

在計算機科學中,二叉樹是每個結點最多有兩個子樹的樹結構。通常子樹被稱作「左子樹」和「右子樹」。

根據不同的用途可分為:

1、完全二叉樹——若設二叉樹的高度為h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第h層有葉子結點,並且葉子結點都是從左到右依次排布,這就是完全二叉樹。

2、滿二叉樹——除了葉結點外每一個結點都有左右子葉且葉子結點都處在最底層的二叉樹。

3、平衡二叉樹——平衡二叉樹又被稱為AVL樹(區別於AVL演算法),它是一棵二叉排序樹,且具有以下性質:它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。

(4)二叉樹與演算法擴展閱讀

深度為h的二叉樹最多有個結點(h>=1),最少有h個結點。對於任意一棵二叉樹,如果其葉結點數為N0,而度數為2的結點總數為N2,則N0=N2+1。

有N個結點的完全二叉樹各結點如果用順序方式存儲,則結點之間有如下關系為若I為結點編號則 如果I>1,則其父結點的編號為I/2。如果2*I<=N,則其左孩子(即左子樹的根結點)的編號為2*I。若2*I>N,則無左孩子。如果2*I+1<=N,則其右孩子的結點編號為2*I+1。

『伍』 最優二叉樹演算法的基本概念

最優二叉樹,也稱哈夫曼(Haffman)樹,是指對於一組帶有確定權值的葉結點,構造的具有最小帶權路徑長度的二叉樹。
那麼什麼是二叉樹的帶權路徑長度呢?
在前面我們介紹過路徑和結點的路徑長度的概念,而二叉樹的路徑長度則是指由根結點到所有葉結點的路徑長度之和。如果二叉樹中的葉結點都具有一定的權值,則可將這一概念加以推廣。設二叉樹具有n個帶權值的葉結點,那麼從根結點到各個葉結點的路徑長度與相應結點權值的乘積之和叫做二叉樹的帶權路徑長度,記為:
WPL= Wk·Lk
其中Wk為第k個葉結點的權值,Lk 為第k個葉結點的路徑長度。如圖7.2所示的二叉樹,它的帶權路徑長度值WPL=2×2+4×2+5×2+3×2=28。
在給定一組具有確定權值的葉結點,可以構造出不同的帶權二叉樹。例如,給出4個葉結點,設其權值分別為1,3,5,7,我們可以構造出形狀不同的多個二叉樹。這些形狀不同的二叉樹的帶權路徑長度將各不相同。圖7.3給出了其中5個不同形狀的二叉樹。
這五棵樹的帶權路徑長度分別為:
(a)WPL=1×2+3×2+5×2+7×2=32
(b)WPL=1×3+3×3+5×2+7×1=29
(c)WPL=1×2+3×3+5×3+7×1=33
(d)WPL=7×3+5×3+3×2+1×1=43
(e)WPL=7×1+5×2+3×3+1×3=29
最優二叉樹演算法 最優二叉樹演算法
由此可見,由相同權值的一組葉子結點所構成的二叉樹有不同的形態和不同的帶權路徑長度,那麼如何找到帶權路徑長度最小的二叉樹(即哈夫曼樹)呢?根據哈夫曼樹的定義,一棵二叉樹要使其WPL值最小,必須使權值越大的葉結點越靠近根結點,而權值越小的葉結點越遠離根結點。
哈夫曼(Haffman)依據這一特點於1952年提出了一種方法,這種方法的基本思想是:
(1)由給定的n個權值{W1,W2,…,Wn}構造n棵只有一個葉結點的二叉樹,從而得到一個二叉樹的集合F={T1,T2,…,Tn};
(2)在F中選取根結點的權值最小和次小的兩棵二叉樹作為左、右子樹構造一棵新的二叉樹,這棵新的二叉樹根結點的權值為其左、右子樹根結點權值之和;
(3)在集合F中刪除作為左、右子樹的兩棵二叉樹,並將新建立的二叉樹加入到集合F中;
(4)重復(2)(3)兩步,當F中只剩下一棵二叉樹時,這棵二叉樹便是所要建立的哈夫曼樹。

『陸』 二叉樹的演算法

如果一棵具有n個結點的深度為k的二叉樹,它的每一個結點都與深度為k的滿二叉樹中編號為1~n的結點一一對應,這棵二叉樹稱為完全二叉樹。
可以根據公式進行推導,假設n0是度為0的結點總數(即葉子結點數),n1是度為1的結點總數,n2是度為2的結點總數,由二叉樹的性質可知:n0=n2+1,則n= n0+n1+n2(其中n為完全二叉樹的結點總數),由上述公式把n2消去得:n= 2n0+n1-1,由於完全二叉樹中度為1的結點數只有兩種可能0或1,由此得到n0=(n+1)/2或n0=n/2,合並成一個公式:n0=(n+1)/2 ,就可根據完全二叉樹的結點總數計算出葉子結點數。

因此葉子結點數是(839+1)/2=420

『柒』 二叉樹演算法

二叉樹是沒有度為1的結點。
完全二叉樹定義:
若設二叉樹的高度為h,除第
h
層外,其它各層
(1~h-1)
的結點數都達到最大個數,第
h
層從右向左連續缺若干結點,這就是完全二叉樹。
完全二叉樹葉子結點的演算法:
如果一棵具有n個結點的深度為k的二叉樹,它的每一個結點都與深度為k的滿二叉樹中編號為1~n的結點一一對應,這棵二叉樹稱為完全二叉樹。
可以根據公式進行推導,假設n0是度為0的結點總數(即葉子結點數),n1是度為1的結點總數,n2是度為2的結點總數,由二叉樹的性質可知:n0=n2+1,則n=
n0+n1+n2(其中n為完全二叉樹的結點總數),由上述公式把n2消去得:n=
2n0+n1-1,由於完全二叉樹中度為1的結點數只有兩種可能0或1,由此得到n0=(n+1)/2或n0=n/2,合並成一個公式:n0=(n+1)/2
,就可根據完全二叉樹的結點總數計算出葉子結點數。
因此葉子結點數是(839+1)/2=420

『捌』 二叉樹的深度演算法怎麼算啊

二叉樹的深度演算法:
一、遞歸實現基本思想:
為了求得樹的深度,可以先求左右子樹的深度,取二者較大者加1即是樹的深度,遞歸返回的條件是若節點為空,返回0
演算法:
1
int
FindTreeDeep(BinTree
BT){
2
int
deep=0;
3
if(BT){
4
int
lchilddeep=FindTreeDeep(BT->lchild);
5
int
rchilddeep=FindTreeDeep(BT->rchild);
6
deep=lchilddeep>=rchilddeep?lchilddeep+1:rchilddeep+1;
7
}
8
return
deep;
9
}
二、非遞歸實現基本思想:
受後續遍歷二叉樹思想的啟發,想到可以利用後續遍歷的方法來求二叉樹的深度,在每一次輸出的地方替換成算棧S的大小,遍歷結束後最大的棧S長度即是棧的深度。
演算法的執行步驟如下:
(1)當樹非空時,將指針p指向根節點,p為當前節點指針。
(2)將p壓入棧S中,0壓入棧tag中,並令p執行其左孩子。
(3)重復步驟(2),直到p為空。
(4)如果tag棧中的棧頂元素為1,跳至步驟(6)。從右子樹返回
(5)如果tag棧中的棧頂元素為0,跳至步驟(7)。從左子樹返回
(6)比較treedeep與棧的深度,取較大的賦給treedeep,對棧S和棧tag出棧操作,p指向NULL,並跳至步驟(8)。
(7)將p指向棧S棧頂元素的右孩子,彈出棧tag,並把1壓入棧tag。(另外一種方法,直接修改棧tag棧頂的值為1也可以)
(8)循環(2)~(7),直到棧為空並且p為空
(9)返回treedeep,結束遍歷
1
int
TreeDeep(BinTree
BT
){
2
int
treedeep=0;
3
stack
S;
4
stack
tag;
5
BinTree
p=BT;
6
while(p!=NULL||!isEmpty(S)){
7
while(p!=NULL){
8
push(S,p);
9
push(tag,0);
10
p=p->lchild;
11
}
12
if(Top(tag)==1){
13
deeptree=deeptree>S.length?deeptree:S.length;
14
pop(S);
15
pop(tag);
16
p=NULL;
17
}else{
18
p=Top(S);
19
p=p->rchild;
20
pop(tag);
21
push(tag,1);
22
}
23
}
24
return
deeptree;
25
}

『玖』 有關二叉樹遞歸的演算法

靠,縮進全被網路搞亂了,自己排版

#include <iostream>
using namespace std;
//二叉樹節點
struct BiTreeNode{
int data;
BiTreeNode *left;
BiTreeNode *right;
};
//寫一個類,方便二叉樹的建立和刪除
class BiTree{
private:
void deleteAllNode(BiTreeNode *root);
public:
BiTreeNode *root;
BiTree();
~BiTree();
void CreateTree();
void deleteLeaves(BiTreeNode *root);
bool DepthOfTheNode(BiTreeNode *currentNode,BiTreeNode *p, int depthOfFather);
void FindMaxValue(BiTreeNode *currentNode, int *maxValue);
void ExchangeLeftAndRight(BiTreeNode *currentNode);
void OutputValueAndDepthByQIANXU(BiTreeNode *currentNode, int depthOfFather); //不好意思,用了拼音
};
BiTree::BiTree()
{
root = NULL;
}
BiTree::~BiTree()
{
deleteAllNode(root);
}
void BiTree::deleteAllNode(BiTreeNode *root)
{
if (root == NULL) return;
deleteAllNode(root->left);
deleteAllNode(root->right);
cout << root->data << ' '; //用來查看當前節點是不是被刪除。
delete root;
}
//手動建立一個二叉樹用於測試
// 1
// / \
// 2 3
// \ /
// 4 5
void BiTree::CreateTree()
{
if (root) return;
root = new BiTreeNode;
root->data = 1;
root->left = new BiTreeNode;
root->left->data = 2;
root->right = new BiTreeNode;
root->right->data = 3;
BiTreeNode *p;
p = root->left;
p->left = NULL;
p->right = new BiTreeNode;
p->right->data = 4;
p->right->left = p->right->right = NULL;
p= root->right;
p->left = new BiTreeNode;
p->left->data = 5;
p->left->left = p->left->right = NULL;
p->right = NULL;
}
//用遞歸演算法刪除葉子
void BiTree::deleteLeaves(BiTreeNode *root)
{
if (root == NULL) return;
if (!root->left && !root->right) return; //表示是根節點(或者出錯,跑到葉子節點了,這種情況應該不會),不刪除

if (root->left) //當前節點有左子樹
{
if (root->left->left || root->left->right) //左子樹不是葉子
deleteLeaves(root->left);
else //當前節點的左子節點是葉子
{
delete root->left;
root->left = NULL;
}
}
if (root->right)
{
if (root->right->left || root->right->right)
deleteLeaves(root->right);
else //當前節點的右子節點是葉子
{
delete root->right;
root->right = NULL;
}
}
}
int depth = 0; //一個用來存儲深度的全局變數,雖然在實際編程中這樣用不好
//但一切為了方便。
//節點p的深度,遞歸法
bool BiTree::DepthOfTheNode(BiTreeNode *currentNode,BiTreeNode *p, int depthOfFather)
{
if (currentNode == NULL) return false;
if (currentNode == p) //當前節點為要找的節點
{
depth = depthOfFather + 1;
return true;;
}
if (DepthOfTheNode(currentNode->left, p, depthOfFather+1)) //找當前節點的左子樹
return true;
else
return DepthOfTheNode(currentNode->right, p, depthOfFather+1);
}
//用遞歸找最大值,最大值存儲在maxValue所指的內存 ,這里使用前序遍歷
void BiTree::FindMaxValue(BiTreeNode *currentNode, int *maxValue)
{
if (currentNode == NULL) return;
*maxValue = *maxValue > currentNode->data ? *maxValue : currentNode->data;
FindMaxValue(currentNode->left, maxValue); //遍歷左子樹
FindMaxValue(currentNode->right, maxValue);
}
//交換左右,用前序遍歷
void BiTree::ExchangeLeftAndRight(BiTreeNode *currentNode)
{
if (currentNode == NULL) return;
BiTreeNode *temp;
temp = currentNode->left;
currentNode->left = currentNode->right;
currentNode->right = temp;
ExchangeLeftAndRight(currentNode->left);
ExchangeLeftAndRight(currentNode->right);
}
//以前序次序輸出一棵二叉樹所有結點的數據值及結點所在層次
void BiTree::OutputValueAndDepthByQIANXU(BiTreeNode *currentNode, int depthOfFather)
{
if (currentNode == NULL) return;
cout << "節點:" << currentNode->data;
cout << "\t深度:" << depthOfFather+1 << endl;
OutputValueAndDepthByQIANXU(currentNode->left, depthOfFather+1);
OutputValueAndDepthByQIANXU(currentNode->right, depthOfFather+1);
}
int main()
{
BiTree bt;
bt.CreateTree();
//求p的深度
bt.DepthOfTheNode(bt.root, bt.root->left->right, 0);
cout << "深度:" << depth << endl;
//找最大值
int maxValue;
bt.FindMaxValue(bt.root, &maxValue);
cout << "最大值為:" << maxValue << endl;
//交換左右節點
bt.ExchangeLeftAndRight(bt.root);
//以前序次序輸出一棵二叉樹所有結點的數據值及結點所在層次
bt.OutputValueAndDepthByQIANXU(bt.root, 0);
//刪除葉子節點
bt.deleteLeaves(bt.root);
return 0;
}

熱點內容
hp存儲擴容 發布:2024-11-17 23:29:16 瀏覽:566
在ftp中put表示什麼 發布:2024-11-17 23:29:12 瀏覽:380
mvc多文件上傳 發布:2024-11-17 23:13:56 瀏覽:152
玩游戲硬碟緩存32m 發布:2024-11-17 23:03:42 瀏覽:522
藍光存儲系統 發布:2024-11-17 23:03:41 瀏覽:433
地平線4提示配置低於最低怎麼辦 發布:2024-11-17 22:54:38 瀏覽:608
注冊銀行卡賬戶密碼填什麼 發布:2024-11-17 22:54:35 瀏覽:535
java壓縮上傳圖片 發布:2024-11-17 22:26:59 瀏覽:625
plc編程課件 發布:2024-11-17 22:18:23 瀏覽:467
我的世界伺服器信號一直在檢測 發布:2024-11-17 22:09:52 瀏覽:545