1. 程式人生 > >以二叉連結串列的方式建立一棵二叉樹,並以非遞迴演算法中序輸出;計算二叉樹的繁茂度,並判斷二叉樹是否為完全二叉樹

以二叉連結串列的方式建立一棵二叉樹,並以非遞迴演算法中序輸出;計算二叉樹的繁茂度,並判斷二叉樹是否為完全二叉樹

以二叉連結串列的方式存二叉樹,輸入時要以先序方式輸入,其中,空子樹用#表示。

二叉樹的繁茂度定義為其高度乘其每層結點最大值。演算法為先用遞迴演算法求二叉樹高度:其高度為左右子樹最大值加1,所以用先序遍歷,定義ld與rd分別為左右子樹高度,最後返回其較大值加1即可。二叉樹寬度採用層次遍歷,用佇列來存樹中元素,設三個變數分別表示每層結點數,每層最後一個結點在隊中位置與寬度。

判斷是否為完全二叉樹的演算法為:以層次遍歷,只要遇到結點沒有左右子樹或只有左子樹沒有右子樹,則其後面的所有結點必為葉子結點。分為三種情況:層次遍歷只有右子樹沒有左子樹則輸出“二叉樹不是完全二叉樹”,返回;有左子樹,將其入隊,有右子樹,入對;如果沒有右子樹,則記下此時結點在隊中位置,以後遍歷到的每一個結點都要判斷其是不是葉子結點。

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define maxsize 50
typedef struct BiTNode {                     //樹的結構體
	char data; 
	struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
BiTree T;
typedef struct stack{                        //中序遍歷所用的棧
	BiTree data[maxsize];
	int top;
}Seqstack;
Seqstack s;
BiTree createBiTree(BiTree &T);       
void zhongxu(BiTree T);
int deep(BiTree T);
int ss(BiTree T);
void judge(BiTree T);
void main(){
	int h,d;
	T=(BiTNode*)malloc(sizeof(BiTNode));
	printf("請以先序輸入一個樹\n");
	createBiTree(T);
	printf("\n");
	printf("中序輸出為:\n");
	zhongxu(T);
	printf("\n");
	h=deep(T);
	d=ss(T);
	printf("\n");
	printf("樹的繁茂度為:%d\n",h*d);
	printf("\n");
	judge(T);
}
BiTree createBiTree(BiTree &T){                     //建立一棵樹,以先序輸入
	char ch;
	scanf("%c",&ch);
	if(ch=='#')T=NULL;
	else{
		T=(BiTNode*)malloc(sizeof(BiTNode));
		T->data=ch;
		createBiTree(T->lchild);                    //遞迴演算法
		createBiTree(T->rchild);
	}
	return T;
}
void zhongxu(BiTree T){                             //中序遍歷,用棧來實現非遞迴
	BiTree h;
	s.top=-1;
	h=(BiTNode*)malloc(sizeof(BiTNode));
	h=T;
	while(h||(s.top!=-1)){
		while(h){
			s.data[++s.top]=h;
			h=h->lchild;
		}
		if(s.top!=-1){
			h=s.data[s.top--];
			printf("%c",h->data);
			h=h->rchild;
		}
	}
}
int deep(BiTree T){                             //求二叉樹高度,遞迴演算法
	int d1,d2,d;
	if(T==NULL)return 0;
	else{
		d1=deep(T->lchild);
		d2=deep(T->rchild);
		if(d1>=d2)d=d1+1;
		else d=d2+1;
	}
	return d;
}
int ss(BiTree T){                                //求二叉樹寬度
	BiTree Q[maxsize],p;
	int f=0,r=0,count=0,m=0,width=0;
	if(T==NULL)return 0;
	Q[r]=T;
	while(f<=m){
		p=Q[f++];
		count++;
		if(p->lchild){
			if(r>=maxsize){printf("overflow");exit(0);}
			Q[++r]=p->lchild;
		}
		if(p->rchild){
			if(r>=maxsize){printf("overflow");exit(0);}
			Q[++r]=p->rchild;
		}
		if(f>m){
			m=r;
			if(count>width)width=count;
			count=0;
		}
	}
	return width;
}
void judge(BiTree T){                              //判斷是否為完全二叉樹
	BiTree q[maxsize],p;
	int f=0,r=0,i=-1;
	if(T==NULL){
		printf("二叉樹為完全二叉樹\n");
		return;
	}
	q[r++]=T; 
	while(f!=r){
		p=q[f++];
		if(p->lchild==NULL&&p->rchild!=NULL){printf("二叉樹不是完全二叉樹\n");return;}
		if(p->lchild!=NULL){
			q[r++]=p->lchild;
			if(p->rchild!=NULL)q[r++]=p->rchild;
			else
				i=f;
		}	
		while(i>-1&&i<=r-1){
			if(q[i]->lchild!=NULL||q[i]->rchild!=NULL){
				printf("二叉樹不是完全二叉樹\n");
				return;
			}
			i++;
		}
	}
	printf("二叉樹為完全二叉樹\n");
}




相關推薦

連結串列方式建立演算法輸出計算繁茂判斷是否完全

以二叉連結串列的方式存二叉樹,輸入時要以先序方式輸入,其中,空子樹用#表示。 二叉樹的繁茂度定義為其高度乘其每層結點最大值。演算法為先用遞迴演算法求二叉樹高度:其高度為左右子樹最大值加1,所以用先序遍歷,定義ld與rd分別為左右子樹高度,最後返回其較大值加1即可。二叉樹寬度

遍歷的演算法實現

linux c++ 模板類 討論範圍 本部落格只實現二叉樹非遞迴演算法的遍歷,請自行學習二叉樹和模板類等相關知識。程式碼中附帶大量註釋,所以就不在進行詳細說明。 中序遍歷 template <typename T>void Post<T>

的先遍歷()、遍歷()、後遍歷()及層次遍歷java實現

二叉樹的先序遍歷,遞迴實現: public List<Integer> preorderTraversal(TreeNode root) { //用棧來實現 List<Integer> list = new ArrayList&l

遍歷演算法實現先和後續遍歷)(實現和先續)

二叉樹遍歷 這兩天抓緊把二叉樹遍歷複習了一遍,遞迴實現還是一如既往地簡潔,迭代版本寫了好久還是隻實現了先序和中序,後續一直沒搞明白,有空了再更新。 遞迴實現 void RecursionBackTree(TreeNode * root) {

遍歷之演算法

在前一篇文章二叉樹遍歷遞迴演算法對二叉樹遍歷的遞迴演算法做了總結,這篇文章就來對二叉樹遍歷的非遞迴演算法做個彙總。還是與上一篇文章一樣的順序,一一彙總先序、中序、後序以及層序遍歷的非遞迴演算法。 1、先序遍歷(非遞迴演算法) 先序遍歷非遞迴訪問,使用棧即可實現。先序遍

資料結構----遍歷的演算法實現

#include <stdio.h>   #include <stdlib.h>   #include <string.h>      #define OK 0;   #define ERROR -1   #define OVERFLOW

不需要棧的遍歷的演算法

talk is cheap, show you the code ... #include<stdio.h> #include<stdlib.h> struct tNode { int data; struct tNode* lef

遍歷的演算法

最近看了二叉樹一章的資料結構內容,知道樹這一章的遍歷,根據字元序列建立二叉樹,建立線索樹,樹與二叉樹的轉換,這些都涉及到了遞迴演算法,都是先將問問題規模縮小,利用森林與二叉樹之間的遞迴定義來巧妙的解決問題,看起來很複雜的問題,用遞迴很容易就解決了。 我們知道用遞迴演算法的時

擴充套件的先遍歷序列建立連結串列方式儲存的遍歷

1. 請根據使用者輸入的“擴充套件的先序遍歷序列”(用小圓點表示空子樹),建立以二叉連結串列方式儲存的二叉樹,然後寫出後序遍歷該二叉樹的非遞迴演算法,並將對應的程式除錯執行通過。 #include<stdio.h> #include<std

【資料結構週週練】014 利用棧和演算法求鏈式儲存的是否完全

一、前言 首先,明天是個很重要的節日,以後我也會過這個節日,在這裡,提前祝所有程式猿們,猿猴節快樂,哦不,是1024程式設計師節快樂。 今天要給大家分享的演算法是判斷二叉樹是否為完全二叉樹,相信大家對完全二叉樹的概念並不陌生,如果是順序儲存就會很方便,那鏈式儲存怎麼判斷呢,我的做法是:若

(先、、後、層次遍歷判斷同構和是否完全

二叉樹基本操作 二叉樹的結構定義 二叉樹的建立(遞迴) 訪問節點 先序遍歷 中序遍歷 後序遍歷 層次遍歷 判斷是否同構 判斷一顆二叉樹是否為完全二叉樹 二叉樹的結構定義

(1)建立二叉樹二叉連結串列。 (2)寫出對用二叉連結串列儲存的二叉樹進行先中序和後遍歷的遞迴非遞迴演算法。 (3)寫出對用二叉連結串列儲存的二叉樹進行層次遍歷演算法。 (4)求二叉樹的所有葉子及結點總數。

(1)建立二叉樹的二叉連結串列。 (2)寫出對用二叉連結串列儲存的二叉樹進行先序、中序和後序遍歷的遞迴和非遞迴演算法。 (3)寫出對用二叉連結串列儲存的二叉樹進行層次遍歷演算法。(4)求二叉樹的所有葉子及結點總數。 include<stdio.h> #inclu

資料結構實驗-C語言-二叉樹建立,前、、後遍歷的遞迴演算法非遞迴演算法,求葉子結點數目二叉樹深度,判斷二叉樹是否相似二叉樹左右子互換,二叉樹遍歷的演算法,判斷二叉樹是否是完全二叉樹

1.實驗目的 熟練掌握二叉樹的二叉連結串列儲存結構的C語言實現。掌握二叉樹的基本操作-前序、中序、後序遍歷二叉樹的三種方法。瞭解非遞迴遍歷過程中“棧”的作用和狀態,而且能靈活運用遍歷演算法實現二叉樹的其它操作。 2.實驗內容 (1)二叉樹的二叉連結串列的建立 (2)二叉樹的前、中、後

的先//後)+層遍歷

queue 的基本操作舉例如下: queue入隊,如例:q.push(x); 將x 接到佇列的末端。 queue出隊,如例:q.pop(); 彈出佇列的第一個元素,注意,並不會返回被彈出元素的值。 訪問queue隊首元素,如例:q.front(),即最早被壓入佇列的元素。 訪問que

【資料結構週週練】013 利用棧和演算法的高

一、前言 二叉樹的高是樹比較重要的一個概念,指的是樹中結點的最大層數本次演算法通過非遞迴演算法來求得樹的高度,借用棧來實現樹中結點的儲存。 學英語真的很重要,所以文中的註釋還有輸出以後會盡量用英語寫,文中出現的英語語法或者單詞使用錯誤,還希望各位英語大神能不吝賜教。 二、題目 將

【資料結構週週練】012 利用佇列和演算法實現的層次遍歷

一、前言 二叉樹的遍歷是比較多樣化的遍歷,有很多種遍歷方式,先序遍歷,中序遍歷,後序遍歷,層次遍歷等等。本次給大家講的是層次遍歷,為了方便,我將題目中的資料改為編號,從左往右,從上往下依次遍歷。方便大家看到結果。 二、題目 將下圖用二叉樹存入,並通過層次遍歷方式,自上而下,從左往右對

c++的前和後遍歷以及層遍歷

二叉樹的遞迴版的前序,中序和後序遍歷很簡單也很容易理解,這裡就放一個前序遍歷的例子 //前序遍歷遞迴演算法,遞迴演算法都大同小異,這裡就不一一列舉了 void binaryTree::pro_order(NodeStack::Node *t) { NodeStack::Node *h = t;

的後遍歷-演算法

同樣的,建立的演算法在先序中有,略去。 後序遞迴遍歷演算法 void PostOrder(BiTree bt){ if(bt){ PostOrder(bt->lchild); PostOrder(bt->rchild); cout<<bt-

遍歷-演算法

建立二叉樹就不說了,這裡直接: 中序遞迴遍歷演算法 void InOrder(BiTree T){ if(T){ InOrder(T->lchild); cout<<T->data<<" "; InOrder(T->rch

的先遍歷-演算法

需要實踐先序遍歷,我們先建立二叉樹。這裡採用先序序列建立二叉樹,不為別的,因為簡單。 typedef int ElemType; typedef struct BiTNode{ ElemType data; struct BiTNode *lchild, *rchild; }*BiTre