導航:首頁 > 源碼編譯 > 二叉樹相關演算法

二叉樹相關演算法

發布時間:2022-06-01 16:15:19

⑴ 有關二叉樹遞歸的演算法

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

#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;
}

⑵ 按照二叉樹的遞歸定義,對二叉樹遍歷的常用演算法有哪三種

/*1 、前序遍歷二叉樹的遞歸演算法 */
void preorder(bintree t)
{
if (t) {
printf("%c",t->data);
preorder(t->lchild);
preorder(t->rchild);
}
}
/*2 、中序遍歷二叉樹的遞歸演算法 */
void inorder(bintree t)
{
if (t) {
inorder(t->lchild);
printf("%c",t->data);
inorder(t->rchild);
}
}
/*3 、後序遍歷二叉樹的遞歸演算法 */
void postorder(bintree t)
{
if (t) {
postorder(t->lchild);
postorder(t->rchild);
printf("%c",t->data);
}
}

⑶ 二叉樹遍歷的演算法實現

從二叉樹的遞歸定義可知,一棵非空的二叉樹由根結點及左、右子樹這三個基本部分組成。因此,在任一給定結點上,可以按某種次序執行三個操作:
⑴訪問結點本身(N),
⑵遍歷該結點的左子樹(L),
⑶遍歷該結點的右子樹(R)。
以上三種操作有六種執行次序:
NLR、LNR、LRN、NRL、RNL、RLN。
注意:
前三種次序與後三種次序對稱,故只討論先左後右的前三種次序。 根據訪問結點操作發生位置命名:
① NLR:前序遍歷(PreorderTraversal亦稱(先序遍歷))
——訪問根結點的操作發生在遍歷其左右子樹之前。
② LNR:中序遍歷(InorderTraversal)
——訪問根結點的操作發生在遍歷其左右子樹之中(間)。
③ LRN:後序遍歷(PostorderTraversal)
——訪問根結點的操作發生在遍歷其左右子樹之後。
注意:
由於被訪問的結點必是某子樹的根,所以N(Node)、L(Left subtree)和R(Right subtree)又可解釋為根、根的左子樹和根的右子樹。NLR、LNR和LRN分別又稱為先根遍歷、中根遍歷和後根遍歷。 1.先(根)序遍歷的遞歸演算法定義:
若二叉樹非空,則依次執行如下操作:
⑴ 訪問根結點;
⑵ 遍歷左子樹;
⑶ 遍歷右子樹。
2.中(根)序遍歷的遞歸演算法定義:
若二叉樹非空,則依次執行如下操作:
⑴遍歷左子樹;
⑵訪問根結點;
⑶遍歷右子樹。
3.後(根)序遍歷得遞歸演算法定義:
若二叉樹非空,則依次執行如下操作:
⑴遍歷左子樹;
⑵遍歷右子樹;
⑶訪問根結點。 用二叉鏈表做為存儲結構,中序遍歷演算法可描述為:
void InOrder(BinTree T)
{ //演算法里①~⑥是為了說明執行過程加入的標號
① if(T) { // 如果二叉樹非空
② InOrder(T->lchild);
③ printf(%c,T->data); // 訪問結點
④ InOrder(T->rchild);
⑤ }
⑥ } // InOrder 計算中序遍歷擁有比較簡單直觀的投影法,如圖
⑴在搜索路線中,若訪問結點均是第一次經過結點時進行的,則是前序遍歷;若訪問結點均是在第二次(或第三次)經過結點時進行的,則是中序遍歷(或後序遍歷)。只要將搜索路線上所有在第一次、第二次和第三次經過的結點分別列表,即可分別得到該二叉樹的前序序列、中序序列和後序序列。
⑵上述三種序列都是線性序列,有且僅有一個開始結點和一個終端結點,其餘結點都有且僅有一個前驅結點和一個後繼結點。為了區別於樹形結構中前驅(即雙親)結點和後繼(即孩子)結點的概念,對上述三種線性序列,要在某結點的前驅和後繼之前冠以其遍歷次序名稱。
【例】上圖所示的二叉樹中結點C,其前序前驅結點是D,前序後繼結點是E;中序前驅結點是E,中序後繼結點是F;後序前驅結點是F,後序後繼結點是A。但是就該樹的邏輯結構而言,C的前驅結點是A,後繼結點是E和F。
二叉鏈表基本思想
基於先序遍歷的構造,即以二叉樹的先序序列為輸入構造。
注意:
先序序列中必須加入虛結點以示空指針的位置。
【例】
建立上圖所示二叉樹,其輸入的先序序列是:ABD∮∮∮CE∮∮F∮∮。
構造演算法
假設虛結點輸入時以空格字元表示,相應的構造演算法為:
void CreateBinTree (BinTree **T){ //構造二叉鏈表。T是指向根指針的指針,故修改*T就修改了實參(根指針)本身 char ch; if((ch=getchar())=='') *T=NULL; //讀入空格,將相應指針置空 else{ //讀人非空格 *T=(BinTNode *)malloc(sizeof(BinTNode)); //生成結點 (*T)->data=ch; CreateBinTree(&(*T)->lchild); //構造左子樹 CreateBinTree(&(*T)->rchild); //構造右子樹 }}
注意:
調用該演算法時,應將待建立的二叉鏈表的根指針的地址作為實參。
示例
設root是一根指針(即它的類型是BinTree),則調用CreateBinTree(&root)後root就指向了已構造好的二叉鏈表的根結點。
二叉樹建立過程見
下面是關於二叉樹的遍歷、查找、刪除、更新數據的代碼(遞歸演算法): #include<iostream>#include<cstdio>#include<cmath>#include<iomanip>#include<cstdlib>#include<ctime>#include<algorithm>#include<cstring>#include<string>#include<vector>#include<list>#include<stack>#include<queue>#include<map>#include<set>usingnamespacestd;typedefintT;classbst{structNode{Tdata;Node*L;Node*R;Node(constT&d,Node*lp=NULL,Node*rp=NULL):data(d),L(lp),R(rp){}};Node*root;intnum;public:bst():root(NULL),num(0){}voidclear(Node*t){if(t==NULL)return;clear(t->L);clear(t->R);deletet;}~bst(){clear(root);}voidclear(){clear(root);num=0;root=NULL;}boolempty(){returnroot==NULL;}intsize(){returnnum;}TgetRoot(){if(empty())throwemptytree;returnroot->data;}voidtravel(Node*tree){if(tree==NULL)return;travel(tree->L);cout<<tree->data<<'';travel(tree->R);}voidtravel(){travel(root);cout<<endl;}intheight(Node*tree){if(tree==NULL)return0;intlh=height(tree->L);intrh=height(tree->R);return1+(lh>rh?lh:rh);}intheight(){returnheight(root);}voidinsert(Node*&tree,constT&d){if(tree==NULL)tree=newNode(d);elseif(ddata)insert(tree->L,d);elseinsert(tree->R,d);}voidinsert(constT&d){insert(root,d);num++;}Node*&find(Node*&tree,constT&d){if(tree==NULL)returntree;if(tree->data==d)returntree;if(ddata)returnfind(tree->L,d);elsereturnfind(tree->R,d);}boolfind(constT&d){returnfind(root,d)!=NULL;}boolerase(constT&d){Node*&pt=find(root,d);if(pt==NULL)returnfalse;combine(pt->L,pt->R);Node*p=pt;pt=pt->R;deletep;num--;returntrue;}voidcombine(Node*lc,Node*&rc){if(lc==NULL)return;if(rc==NULL)rc=lc;elsecombine(lc,rc->L);}boolupdate(constT&od,constT&nd){Node*p=find(root,od);if(p==NULL)returnfalse;erase(od);insert(nd);returntrue;}};intmain(){bstb;cout<<inputsomeintegers:;for(;;){intn;cin>>n;b.insert(n);if(cin.peek()==' ')break;}for(;;){cout<<inputdatapair:;intod,nd;cin>>od>>nd;if(od==-1&&nd==-1)break;b.update(od,nd);}}

⑷ 二叉樹結點的演算法

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

⑸ 二叉樹的層次遍歷演算法

二叉樹的層次遍歷演算法有如下三種方法:

給定一棵二叉樹,要求進行分層遍歷,每層的節點值單獨列印一行,下圖給出事例結構:

之後大家就可以自己畫圖了,下面給出程序代碼:

[cpp] view plain

void print_by_level_3(Tree T) {

vector<tree_node_t*> vec;

vec.push_back(T);

int cur = 0;

int end = 1;

while (cur < vec.size()) {

end = vec.size();

while (cur < end) {

cout << vec[cur]->data << " ";

if (vec[cur]->lchild)

vec.push_back(vec[cur]->lchild);

if (vec[cur]->rchild)

vec.push_back(vec[cur]->rchild);

cur++;

}

cout << endl;

}

}


最後給出完成代碼的測試用例:124##57##8##3#6##

[cpp] view plain

#include<iostream>

#include<vector>

#include<deque>

using namespace std;

typedef struct tree_node_s {

char data;

struct tree_node_s *lchild;

struct tree_node_s *rchild;

}tree_node_t, *Tree;

void create_tree(Tree *T) {

char c = getchar();

if (c == '#') {

*T = NULL;

} else {

*T = (tree_node_t*)malloc(sizeof(tree_node_t));

(*T)->data = c;

create_tree(&(*T)->lchild);

create_tree(&(*T)->rchild);

}

}

void print_tree(Tree T) {

if (T) {

cout << T->data << " ";

print_tree(T->lchild);

print_tree(T->rchild);

}

}

int print_at_level(Tree T, int level) {

if (!T || level < 0)

return 0;

if (0 == level) {

cout << T->data << " ";

return 1;

}

return print_at_level(T->lchild, level - 1) + print_at_level(T->rchild, level - 1);

}

void print_by_level_1(Tree T) {

int i = 0;

for (i = 0; ; i++) {

if (!print_at_level(T, i))

break;

}

cout << endl;

}

void print_by_level_2(Tree T) {

deque<tree_node_t*> q_first, q_second;

q_first.push_back(T);

while(!q_first.empty()) {

while (!q_first.empty()) {

tree_node_t *temp = q_first.front();

q_first.pop_front();

cout << temp->data << " ";

if (temp->lchild)

q_second.push_back(temp->lchild);

if (temp->rchild)

q_second.push_back(temp->rchild);

}

cout << endl;

q_first.swap(q_second);

}

}

void print_by_level_3(Tree T) {

vector<tree_node_t*> vec;

vec.push_back(T);

int cur = 0;

int end = 1;

while (cur < vec.size()) {

end = vec.size();

while (cur < end) {

cout << vec[cur]->data << " ";

if (vec[cur]->lchild)

vec.push_back(vec[cur]->lchild);

if (vec[cur]->rchild)

vec.push_back(vec[cur]->rchild);

cur++;

}

cout << endl;

}

}

int main(int argc, char *argv[]) {

Tree T = NULL;

create_tree(&T);

print_tree(T);

cout << endl;

print_by_level_3(T);

cin.get();

cin.get();

return 0;

}

⑹ 二叉樹演算法

二叉樹是沒有度為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

⑺ 求二叉樹的基本演算法和各種遍歷演算法

#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;
}

⑻ 二叉樹相關演算法的實驗驗證 [ 實驗目的] 驗證二叉樹的鏈接存儲結構及其上的基本操作。(c++)

淺談數據結構-二叉樹

二叉樹是樹的特殊一種,具有如下特點:1、每個結點最多有兩顆子樹,結點的度最大為2。2、左子樹和右子樹是有順序的,次序不能顛倒。3、即使某結點只有一個子樹,也要區分左右子樹。

一、特殊的二叉樹及特點

1、斜樹

所有的結點都只有左子樹(左斜樹),或者只有右子樹(右斜樹)。這就是斜樹,應用較少

基本思想:先後序遍歷左子樹,然後再後序遍歷右子樹,最後再訪問根結點即左—右—根。

圖中後序遍歷結果是:4,8,7,5,2,6,3,1。

後序遞歸遍歷代碼實現,如下所示。

  • //後序遞歸遍歷void PostOrderTraverse(BiTree t)

  • { if(t != NULL)

  • {

  • PostOrderTraverse(t->lchild);

  • PostOrderTraverse(t->rchild);

  • printf("%c ", t->data);

  • }

  • }

  • 後序遍歷的非遞歸實現是三種遍歷方式中最難的一種。因為在後序遍歷中,要保證左孩子和右孩子都已被訪問,並且左孩子在右孩子之前訪問才能訪問根結點,這就為流程式控制制帶來了難題。下面介紹一種思路。

    要保證根結點在左孩子和右孩子訪問之後才能訪問,因此對於任一結點p,先將其入棧。若p不存在左孩子和右孩子,則可以直接訪問它,或者p存在左孩子或右孩子,但是其左孩子和右孩子都已經被訪問過了,則同樣可以直接訪問該結點。若非上述兩種情況,則將p的右孩子和左孩子依次入棧,這樣就保證了每次取棧頂元素的時候,左孩子在右孩子之前別訪問,左孩子和右孩子都在根結點前面被訪問。

  • //後序非遞歸遍歷二叉樹int NoPostOrderTraverse(BiTree t)

  • {

  • SqStack s;

  • InitStack(&s);


  • BiTree cur; //當前結點

  • BiTree pre = NULL; //前一次訪問的結點 BiTree tmp;

  • if(t == NULL)

  • {

  • fprintf(stderr, "the tree is null. "); return ERROR;

  • }


  • Push(&s, t); while(IsEmpty(&s) != 1)

  • {

  • GetTop(&s, &cur);// if((cur->lchild == NULL && cur->rchild == NULL) || (pre != NULL && (pre == cur->lchild || pre == cur->rchild)))

  • {

  • printf("%c ", cur->data); //如果當前結點沒有孩子結點或者孩子結點都已被訪問過

  • Pop(&s, &tmp);

  • pre = cur;

  • } else

  • { if(cur->rchild != NULL)

  • {

  • Push(&s, cur->rchild);

  • } if(cur->lchild != NULL)

  • {

  • Push(&s, cur->lchild);

  • }

  • }

  • } return OK;

  • }

  • 五、二叉樹的建立

    其實而二叉樹的建立就是二叉樹的遍歷,只不過將輸入內容改為建立結點而已,比如,利用前序遍歷建立二叉樹

  • //創建樹//按先後次序輸入二叉樹中結點的值(一個字元),#表示空樹//構造二叉鏈表表示的二叉樹BiTree CreateTree(BiTree t)

  • { char ch;

  • scanf("%c", &ch);

  • if(ch == '#')

  • {

  • t = NULL;

  • } else

  • {

  • t = (BitNode *)malloc(sizeof(BitNode)); if(t == NULL)

  • {

  • fprintf(stderr, "malloc() error in CreateTree. "); return;

  • }


  • t->data = ch; //生成根結點

  • t->lchild = CreateTree(t->lchild); //構造左子樹

  • t->rchild = CreateTree(t->rchild); //構造右子樹 } return t;

  • }

  • ⑼ 二叉樹的深度演算法怎麼算啊

    二叉樹的深度演算法:
    一、遞歸實現基本思想:
    為了求得樹的深度,可以先求左右子樹的深度,取二者較大者加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
    }

    ⑽ 二叉樹的遍歷演算法

    這里有二叉樹先序、中序、後序三種遍歷的非遞歸演算法,此三個演算法可視為標准演算法。
    1.先序遍歷非遞歸演算法
    #define
    maxsize
    100
    typedef
    struct
    {

    Bitree
    Elem[maxsize];

    int
    top;
    }SqStack;
    void
    PreOrderUnrec(Bitree
    t)
    {
    SqStack
    s;
    StackInit(s);
    p=t;
    while
    (p!=null
    ||
    !StackEmpty(s))
    {
    while
    (p!=null)
    //遍歷左子樹
    {
    visite(p->data);
    push(s,p);
    p=p->lchild;
    }//endwhile
    if
    (!StackEmpty(s))
    //通過下一次循環中的內嵌while實現右子樹遍歷
    {
    p=pop(s);
    p=p->rchild;
    }//endif
    }//endwhile
    }//PreOrderUnrec
    2.中序遍歷非遞歸演算法
    #define
    maxsize
    100
    typedef
    struct
    {
    Bitree
    Elem[maxsize];
    int
    top;
    }SqStack;
    void
    InOrderUnrec(Bitree
    t)
    {
    SqStack
    s;
    StackInit(s);
    p=t;
    while
    (p!=null
    ||
    !StackEmpty(s))
    {
    while
    (p!=null)
    //遍歷左子樹
    {
    push(s,p);
    p=p->lchild;
    }//endwhile
    if
    (!StackEmpty(s))
    {
    p=pop(s);
    visite(p->data);
    //訪問根結點
    p=p->rchild;
    //通過下一次循環實現右子樹遍歷
    }//endif
    }//endwhile
    }//InOrderUnrec
    3.後序遍歷非遞歸演算法
    #define
    maxsize
    100
    typedef
    enum{L,R}
    tagtype;
    typedef
    struct
    {
    Bitree
    ptr;
    tagtype
    tag;
    }stacknode;
    typedef
    struct
    {
    stacknode
    Elem[maxsize];
    int
    top;
    }SqStack;
    void
    PostOrderUnrec(Bitree
    t)
    {
    SqStack
    s;
    stacknode
    x;
    StackInit(s);
    p=t;
    do
    {
    while
    (p!=null)
    //遍歷左子樹
    {
    x.ptr
    =
    p;
    x.tag
    =
    L;
    //標記為左子樹
    push(s,x);
    p=p->lchild;
    }
    while
    (!StackEmpty(s)
    &&
    s.Elem[s.top].tag==R)
    {
    x
    =
    pop(s);
    p
    =
    x.ptr;
    visite(p->data);
    //tag為R,表示右子樹訪問完畢,故訪問根結點
    }
    if
    (!StackEmpty(s))
    {
    s.Elem[s.top].tag
    =R;
    //遍歷右子樹
    p=s.Elem[s.top].ptr->rchild;
    }
    }while
    (!StackEmpty(s));
    }//PostOrderUnrec

    閱讀全文

    與二叉樹相關演算法相關的資料

    熱點內容
    單片機最小系統電路設計流程圖 瀏覽:663
    steam源碼 瀏覽:29
    關於對數的運演算法則及公式 瀏覽:775
    明星談如何緩解壓力 瀏覽:141
    androidlistview隱藏列 瀏覽:396
    plc跑馬燈編程 瀏覽:816
    ios開發之網路編程 瀏覽:421
    處理照片視頻哪個app好 瀏覽:386
    logback壓縮 瀏覽:888
    冰箱壓縮機可以用氣割嗎 瀏覽:531
    菜鳥如何加密商品信息 瀏覽:315
    程序員那麼可愛小說結局 瀏覽:866
    zenity命令 瀏覽:570
    監禁風暴哪個app有 瀏覽:871
    程序員的愛心是什麼 瀏覽:595
    java中對字元串排序 瀏覽:296
    單片機用數模轉換生成三角波 瀏覽:640
    外網怎麼登陸伺服器地址 瀏覽:140
    什麼人要懂編譯原理 瀏覽:154
    源碼改單 瀏覽:719