




已閱讀5頁,還剩22頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
數(shù)據(jù)結(jié)構(gòu)與數(shù)據(jù)庫實驗報告實驗題目二叉樹的基本操作及運(yùn)算學(xué)院:化學(xué)與材料科學(xué)學(xué)院專業(yè)班級:09級材料科學(xué)與工程系 PB0920603姓名:李維谷學(xué)號:PB09206285 郵箱:指導(dǎo)教師:賈伯琪實驗時間:2010年10月17日一、 需要分析問題描述:實現(xiàn)二叉樹(包括二叉排序樹)的建立,并實現(xiàn)先序、中序、后序和按層次遍歷,計算葉子結(jié)點(diǎn)數(shù)、樹的深度、樹的寬度,求樹的非空子孫結(jié)點(diǎn)個數(shù)、度為2的結(jié)點(diǎn)數(shù)目、度為2的結(jié)點(diǎn)數(shù)目,以及二叉樹常用運(yùn)算。問題分析:二叉樹樹型結(jié)構(gòu)是一類重要的非線性數(shù)據(jù)結(jié)構(gòu),對它的熟練掌握是學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)的基本要求。由于二叉樹的定義本身就是一種遞歸定義,所以二叉樹的一些基本操作也可采用遞歸調(diào)用的方法。處理本問題,我覺得應(yīng)該:1、 建立二叉樹;2、 通過遞歸方法來遍歷(先序、中序和后序)二叉樹;3、 通過隊列應(yīng)用來實現(xiàn)對二叉樹的層次遍歷;4、 借用遞歸方法對二叉樹進(jìn)行一些基本操作,如:求葉子數(shù)、樹的深度寬度等;5、 運(yùn)用廣義表對二叉樹進(jìn)行廣義表形式的打印。算法規(guī)定:輸入形式:為了方便操作,規(guī)定二叉樹的元素類型都為字符型,允許各種字符類型的輸入,沒有元素的結(jié)點(diǎn)以空格輸入表示,并且本實驗是以先序順序輸入的。輸出形式:通過先序、中序和后序遍歷的方法對樹的各字符型元素進(jìn)行遍歷打印,再以廣義表形式進(jìn)行打印。對二叉樹的一些運(yùn)算結(jié)果以整型輸出。程序功能:實現(xiàn)對二叉樹的先序、中序和后序遍歷,層次遍歷。計算葉子結(jié)點(diǎn)數(shù)、樹的深度、樹的寬度,求樹的非空子孫結(jié)點(diǎn)個數(shù)、度為2的結(jié)點(diǎn)數(shù)目、度為2的結(jié)點(diǎn)數(shù)目。對二叉樹的某個元素進(jìn)行查找,對二叉樹的某個結(jié)點(diǎn)進(jìn)行刪除。測試數(shù)據(jù):輸 入 一:ABCDEGF (以表示空格),查找5,刪除E 預(yù)測結(jié)果:先序遍歷 ABCDEGF 中序遍歷 CBEGDFA 后序遍歷 CGEFDBA 層次遍歷 ABCDEFG 廣義表打印 A(B(C,D(E(,G),F) 葉子數(shù) 3 深度 5 寬度 2 非空子孫數(shù) 6 度為2的數(shù)目 2 度為1的數(shù)目2 查找5,成功,查找的元素為E刪除E后,以廣義表形式打印A(B(C,D(,F) 輸 入 二:ABDEHCFG (以表示空格),查找10,刪除B 預(yù)測結(jié)果:先序遍歷 ABDEHCFG 中序遍歷 DBHEAGFC 后序遍歷 DHEBGFCA 層次遍歷 ABCDEFHG 廣義表打印 A(B(D,E(H),C(F(,G)) 葉子數(shù) 3 深度 4 寬度 3 非空子孫數(shù) 7 度為2的數(shù)目 2 度為1的數(shù)目3 查找10,失敗。刪除B后,以廣義表形式打印A(,C(F(,G)二、 概要設(shè)計程序中將涉及下列兩個抽象數(shù)據(jù)類型:一個是二叉樹,一個是隊列。1、設(shè)定“二叉樹”的抽象數(shù)據(jù)類型定義:ADT BiTree數(shù)據(jù)對象D:D是具有相同特性的數(shù)據(jù)元素的集合。數(shù)據(jù)關(guān)系R: 若,則,稱BiTree為空二叉樹; 若,則,H是如下二元關(guān)系:(1) 在D中存在唯一的稱為根的數(shù)據(jù)元素root,它在關(guān)系H下無前驅(qū);(2) 若則存在且;(3) 若則中存在唯一的元素,且存在上的關(guān)系若則中存在唯一的元素,且存在上的關(guān)系;(4) 是一棵符合本定義的二叉樹,稱為根的左子樹,是一棵符合本定義的二叉樹,稱為根的有字樹基本操作: CreateBiTree&T) 操作結(jié)果:按照T的定義構(gòu)造一個二叉樹。 BiTreeDepth(& T) 初始條件:二叉樹T已存在。 操作結(jié)果:返回T的深度。BiTreeWidth(&T)初始條件:二叉樹T已存在。 操作結(jié)果:返回T的寬度。PreOderTraverse&T) 初始條件:二叉樹T已存在。 操作結(jié)果:先序遍歷打印T,InOderTraverse(&T)初始條件:二叉樹T已存在。 操作結(jié)果:中序遍歷打印T。PostOderTraverse(&T)初始條件:二叉樹T已存在。 操作結(jié)果:后序遍歷打印T。LevelTraverse(&T)初始條件:二叉樹T已存在。 操作結(jié)果:層次遍歷T。DeleteXTree(&T,TElemType x)初始條件:二叉樹已存在。 操作結(jié)果:刪除元素為x的結(jié)點(diǎn)以及其左子樹和右子樹。 CopyTree(&T)初始條件:二叉樹T已存在。 操作結(jié)果:以T為模板,復(fù)制另一個二叉樹。ADT BiTree2、設(shè)定隊列的抽象數(shù)據(jù)類型定義:ADT Queue數(shù)據(jù)對象:D=數(shù)據(jù)關(guān)系:R1=|,i=2,,n約定端為隊列頭,端為隊列尾。基本操作: InitQueue(&Q) 操作結(jié)果:構(gòu)造一個空隊列Q。 EnQueue(&Q,&e) 初始條件:隊列Q已存在。 操作結(jié)果:插入元素e為Q的新的隊尾元素。 DeQueue(&Q) 初始條件:隊列Q已存在。 操作結(jié)果:刪除Q的對頭元素,并返回其值。 QueueEmpty(&Q) 初始條件:隊列Q已存在。 操作結(jié)果:若Q為空隊列,則返回1,否則0。 ADT Queue3、本程序包含四個模塊1)主程序模塊void main( )初始化;先序輸入二叉樹各結(jié)點(diǎn)元素;各種遍歷二叉樹;對二叉樹進(jìn)行常見運(yùn)算;復(fù)制二叉樹;在復(fù)制的二叉樹上進(jìn)行二叉樹的常見操作;2)二叉樹模塊實現(xiàn)二叉樹的抽象數(shù)據(jù)類型和基本操作2)隊列模塊實現(xiàn)隊列的抽象數(shù)據(jù)類型及今本操作3)廣義表打印模塊以廣義表形式打印二叉樹4)二叉樹運(yùn)算模塊對二叉樹的葉子、非空子孫結(jié)點(diǎn)數(shù)目、度為2或1的結(jié)點(diǎn)數(shù)三、 詳細(xì)設(shè)計1、主程序中需要的全程量#define M 10 / 統(tǒng)計二叉樹寬度時需用數(shù)組對每層寬度進(jìn)行存儲,這M表示數(shù)組的長度2、隊列的建立與基本操作typedef struct QNodeBiTree data; /隊列中存儲的元素類型struct QNode *next; /指向二叉樹結(jié)點(diǎn)的指針 QNode,*Queueptr;typedef structQueueptr front; /隊列的隊頭指針Queueptr rear; /隊列的隊尾指針LinkQueue;算法描述:為了對二叉樹進(jìn)行層次遍歷,需要“先訪問的結(jié)點(diǎn),其孩子結(jié)點(diǎn)必然也先訪問”,故需運(yùn)用到隊列。而考慮到層次遍歷對隊列操作的需要,只需進(jìn)行隊列的初始化,入隊和出隊以及檢查隊列是否為空。偽碼算法:void InitQueue(LinkQueue *Q)/初始化隊列申請一個結(jié)點(diǎn)Q-front=Q-rear=(Queueptr)malloc(sizeof(QNode);if(!Q-front)exit(1);/存儲分配失敗處理Q-front-next=NULL;/構(gòu)成帶頭結(jié)點(diǎn)里的空鏈隊列void EnQueue(LinkQueue *Q,BiTree e)/插入元素為e為Q的隊尾元素Queueptr q;q=(Queueptr)malloc(sizeof(QNode);if(!q)exit(1);q-data=e;q-next=NULL;Q-rear-next=q; /元素e的結(jié)點(diǎn)入列Q-rear=q;BiTree DeQueue(LinkQueue *Q)/從隊列中刪除隊頭元素,并直接返回給調(diào)用的主函數(shù)Queueptr p;BiTree q;if(Q-front=Q-rear)/隊列為空printf(ERROR!n);exit(1);p=Q-front-next;q=p-data;Q-front-next=p-next; /刪除該結(jié)點(diǎn)if(Q-rear=p)Q-rear=Q-front;free(p);return q;/返回隊頭元素int QueueEmpty(LinkQueue *Q)/檢查隊列是否為空,若為空則返回真值,否則返回0if(Q-front=Q-rear)return 1;elsereturn 0;3、二叉樹的建立與基本操作typedef struct BiTNodeTElemType data; /二叉樹結(jié)點(diǎn)存儲的元素類型struct BiTNode *lchild,*rchild; /二叉樹左右孩子指針BiTNode,*BiTree;算法分析:二叉樹的基本操作是本程序的核心,考慮到二叉樹的定義就是采用遞歸定義,所以很容易想到對二叉樹的操作可通過遞歸調(diào)用來實現(xiàn)。1)二叉樹的遍歷算法描述:二叉樹中常常要求在樹中查找具有某種特征的結(jié)點(diǎn),或者對樹中全部結(jié)點(diǎn)逐一進(jìn)行某種處理,這就需要遍歷二叉樹。即要求按某條路徑尋訪樹中的每個結(jié)點(diǎn),使得每個結(jié)點(diǎn)均被訪問一次,而且僅被訪問一次。回顧二叉樹的遞歸定義可知,二叉樹是由3個基本單元組成:根節(jié)點(diǎn)、左子樹和右子樹。因此,若能依次遍歷這三部分,便是遍歷了整棵二叉樹。如果以L、D、R分別表示遍歷左子樹、訪問根結(jié)點(diǎn)和遍歷右子樹,則可有DLR、LDR、LRD、DRL、RDL、RLD這6種遍歷二叉樹的方案。若限定先右后左,則只有前三種情況,分別稱之為先(根)序遍歷。中(根)序遍歷和后(根)序遍歷?;诙鏄涞倪f歸定義,可得下述遍歷二叉樹的遞歸定義算法。先序遍歷二叉樹的操作定義:若二叉樹為空,則空操作;否則(1) 訪問根結(jié)點(diǎn);(2) 先序遍歷左子樹;(3) 先序遍歷右子樹。偽碼算法:void PreOderTraverse(BiTree T)/采用二叉鏈表存儲結(jié)構(gòu)if(T)putchar(T-data);/最簡單的訪問結(jié)點(diǎn)法,輸出結(jié)點(diǎn)元素,這里先訪問根結(jié)點(diǎn)PreOderTraverse(T-lchild);PreOderTraverse(T-rchild);中序遍歷二叉樹的操作定義:若二叉樹為空,則空操作;否則(1) 中序遍歷左子樹;(2) 訪問根結(jié)點(diǎn);(3) 中序遍歷右子樹。偽碼算法:void InOderTraverse(BiTree T)/采用二叉鏈表存儲結(jié)構(gòu)if(T)InOderTraverse(T-lchild);/先遍歷左子樹putchar(T-data);/ 最簡單的訪問結(jié)點(diǎn)法,輸出結(jié)點(diǎn)元素,這里第二訪問根結(jié)點(diǎn)InOderTraverse(T-rchild); 后序遍歷二叉樹的操作定義:若二叉樹為空,則空操作;否則(1) 后序遍歷左子樹;(2) 后序遍歷右子樹;(3) 訪問根結(jié)點(diǎn)。偽碼算法:void PostOderTraverse(BiTree T)/采用二叉鏈表存儲結(jié)構(gòu)if(T)PostOderTraverse(T-lchild);/先遍歷左子樹PostOderTraverse(T-rchild);/再遍歷右子樹putchar(T-data);/最后訪問根結(jié)點(diǎn) 2)二叉樹的建立算法描述:對二叉樹“遍歷”基本操作已經(jīng)建立的基礎(chǔ)上,可以在便利過程中對結(jié)點(diǎn)進(jìn)行各種操作,如:在遍歷過程中生成結(jié)點(diǎn),建立二叉樹存儲結(jié)構(gòu)。采用先序遍歷建立二叉樹鏈表:(1) 按先序序列輸入二叉樹中結(jié)點(diǎn)的元素,以空格表示空,直到輸入回車為止;(2) 若元素值為空,則賦值NULL;否則生成一個新的結(jié)點(diǎn),將元素值賦值給該跟結(jié)點(diǎn)的數(shù)值域;(3) 建立該跟結(jié)點(diǎn)的左子樹;(4) 建立該根結(jié)點(diǎn)的右子樹。偽碼算法;BiTree CreateBiTree(BiTree T)/構(gòu)造二叉樹T,按先序序列輸入二叉樹中結(jié)點(diǎn)的值(一個字符),空格表示空樹char ch;if(ch=getchar()= )T=NULL;elseif(ch!=n)if(!(T=(BiTree)malloc(sizeof(BiTNode)exit(1);T-data=ch; /生成根結(jié)點(diǎn)T-lchild=CreateBiTree(T-lchild);/構(gòu)造左子樹T-rchild=CreateBiTree(T-rchild);/構(gòu)造右子樹 return T;/返回所構(gòu)造二叉樹(子)樹的地址3)二叉樹的層次遍歷算法分析:有時需要一層層訪問二叉樹,比如判斷二叉樹是否為完全二叉樹、找出指定層中含有的葉子/度為2/度為1的結(jié)點(diǎn)等,這就需要另一種遍歷方法層次遍歷。先訪問的結(jié)點(diǎn),其孩子結(jié)點(diǎn)必然也先訪問,引入隊列存儲已被訪問的,但其左右孩子尚未訪問的結(jié)點(diǎn)的指針。算法描述:(1)若結(jié)點(diǎn)不為空,則訪問該結(jié)點(diǎn),并將其入列;(2)接著從隊列中取已被訪問的,但其左右孩子尚未被訪問的;(3)訪問該結(jié)點(diǎn)的左孩子,將其入列;(4)訪問該結(jié)點(diǎn)的右孩子,將其入列。偽碼算法:int visit(TElemType e)/簡單的結(jié)點(diǎn)訪問函數(shù)if(e)putchar(e);/打印該結(jié)點(diǎn)元素return 1;elsereturn 0;void LevelTraverse(BiTree T)LinkQueue *Q=(LinkQueue *)malloc(sizeof(LinkQueue);BiTree p=(BiTree)malloc(sizeof(BiTNode);InitQueue(Q);/初始化隊列,隊列的元素為二叉樹的結(jié)點(diǎn)指針if(T!=NULL)if(!visit(T-data)/訪問該結(jié)點(diǎn)exit(1);EnQueue(Q,T);/將已被訪問的,但左右孩子沒被訪問的結(jié)點(diǎn)入列while(!QueueEmpty(Q)/隊列不為空,則尚有未被訪問其孩子的結(jié)點(diǎn)p=DeQueue(Q);/將該結(jié)點(diǎn)出列,返回其地址if(p-lchild!=NULL)if(!visit(p-lchild-data)/訪問左孩子exit(1);EnQueue(Q,p-lchild);/將其入列if(p-rchild!=NULL)if(!visit(p-rchild-data)/訪問右孩子exit(1);EnQueue(Q,p-rchild);/將其入列4)求二叉樹的深度算法描述:(1) 若結(jié)點(diǎn)不為空,則求其左子樹的深度,并返回其值h1;(2) 求其右子樹的深度,也返回其值h2;(3) 選擇左右子樹深度的最大值,將其加一(該結(jié)點(diǎn)本身深度)即為該結(jié)點(diǎn)子樹的深度。偽碼算法:int BiTreeDepth(BiTree T)/后序遍歷求樹T所指二叉樹的深度int hl=0,hr=0;if(!T)return 0;elsehl=BiTreeDepth(T-lchild);/求左子樹的深度hr=BiTreeDepth(T-rchild);/求右子樹的深度if(hl=hr)return hl+1;else return hr+1;/子樹深度的最大值再加上本身所在結(jié)點(diǎn)的深度記為子樹的深度5)求二叉樹的寬度算法描述:(1) 定義一個數(shù)組,來存放每層的結(jié)點(diǎn)數(shù),max來存放到這層為止時的最大結(jié)點(diǎn)數(shù);(2) 計算每一層的結(jié)點(diǎn)數(shù)將其賦值給對應(yīng)的數(shù)組元素;(3) 每層計算完后,用max與本層結(jié)點(diǎn)數(shù)比較,若max小,則將本層結(jié)點(diǎn)數(shù)賦值給max;(4) 最后返回max。偽碼算法:int BiTreeWidth(BiTree T,int i)int static nM=0;/存放各層結(jié)點(diǎn)數(shù),M為最先預(yù)料的最大樹的最大深度int static max=0;/最大寬度if(T!=NULL)if(i=1)/若是訪問根結(jié)點(diǎn)ni+;/第一層加1i+;/到第二層if(T-lchild)ni+;/若有左孩子則該層加1if(T-rchild)ni+;/若有右孩子則該層加1else/訪問子樹的結(jié)點(diǎn)i+;/向下一層if(T-lchild)ni+;if(T-rchild)ni+;if(maxlchild,i);/遍歷左子樹BiTreeWidth(T-rchild,i-);/網(wǎng)上退一層后遍歷右子樹return max;6)刪除二叉樹的某個結(jié)點(diǎn)算法描述:(1)先序遍歷找到該結(jié)點(diǎn);(2)若此結(jié)點(diǎn)為空,不必釋放;若不為空,則先釋放其左右子樹的所有結(jié)點(diǎn)的空間,再賦為空;(3)再釋放根結(jié)點(diǎn)的空間,并將這個結(jié)點(diǎn)的父節(jié)點(diǎn)指向該結(jié)點(diǎn)的指針域賦為空。偽碼算法:BiTree DeleteBiTree(BiTree t)/釋放該結(jié)點(diǎn)空間的函數(shù)if(t!=NULL)t-lchild=DeleteBiTree(t-lchild);/釋放其左子樹的空間t-rchild=DeleteBiTree(t-rchild);/釋放右子樹的空間free(t);/釋放根結(jié)點(diǎn)的空間t=NULL;/將其值賦為空return t;BiTree DeleteXTree(BiTree t,TElemType x)/先序查找到需刪結(jié)點(diǎn)位置if(t!=NULL)if(t-data=x)/判斷是否為指定結(jié)點(diǎn)DeleteBiTree(t);/釋放樹的空間t=NULL; elset-lchild=DeleteXTree(t-lchild,x); t-rchild=DeleteXTree(t-rchild,x);return t;7)復(fù)制二叉樹算法描述:(1) 先復(fù)制其左子樹;(2) 再復(fù)制其右子樹;(3) 生成一個新結(jié)點(diǎn),將根復(fù)制。偽碼算法:BiTree GetTreeNode(TElemType item,BiTree lptr,BiTree rptr)/生成一個其元素值為item,左指針為lpttr,右指針為rptr的結(jié)點(diǎn)BiTree t;t=(BiTree)malloc(sizeof(BiTNode);t-data=item;t-lchild=lptr;t-rchild=rptr;return t;BiTree CopyTree(BiTree T)/已知二叉樹的根指針T,返回它的復(fù)制品的根指針BiTree newlptr,newrptr,newnode;if(!T)return NULL;/復(fù)制一顆空樹if(T-lchild)newlptr=CopyTree(T-lchild);/復(fù)制(遍歷)其左子樹elsenewlptr=NULL;if(T-rchild)newrptr=CopyTree(T-rchild); /復(fù)制(遍歷)其右子樹elsenewrptr=NULL;newnode=GetTreeNode(T-data,newlptr,newrptr);/生成根結(jié)點(diǎn)return newnode;4、廣義表形式打印二叉樹算法分析:為了讓打印的二叉樹更形象,更清楚的反映二叉樹各結(jié)點(diǎn)的關(guān)系,采用廣義表形式打印則可以滿足要求。算法描述:(1)打印根結(jié)點(diǎn),若其還有孩子,則輸出“(”;(2)若有左孩子,則打印左子樹;(3)若還有右子樹,則先打印“,”區(qū)分左右孩子,再打印右子樹,并輸出“)”表示輸除完畢。偽碼算法:void print(BiTree T)/廣義表形式打印二叉樹if(T!=NULL)printf(%c,T-data);if(T-lchild!=NULL | T-rchild!=NULL)/該結(jié)點(diǎn)還有孩子printf();print(T-lchild);/廣義表打印左子樹if(T-rchild!=NULL)printf(,);print(T-rchild);/廣義表打印右子樹printf();5、二叉樹的常見運(yùn)算1)求二叉樹的葉子數(shù)算法描述:(1) 若該結(jié)點(diǎn)無孩子,則表示為葉子,計數(shù)器加一;(2) 若該結(jié)點(diǎn)右孩子,求其左子樹的的葉子;(3) 再求其右子樹的葉子。偽碼算法:int LeafNum(BiTree T)/統(tǒng)計葉子數(shù)int static n=0;/定義一個靜態(tài)局部變量作為計數(shù)器if(T!=NULL)if(T-lchild=NULL & T-rchild=NULL)/結(jié)點(diǎn)無孩子n+;/計數(shù)器加一LeafNum(T-lchild);/求左子樹的葉子數(shù)LeafNum(T-rchild); /求右子樹的葉子數(shù)return n;2)求不同的度的結(jié)點(diǎn)數(shù)算法描述:(1) 定義一個靜態(tài)局部數(shù)組變量來統(tǒng)計不同度的結(jié)點(diǎn)數(shù)(2) 若該結(jié)點(diǎn)既有左孩子又有右孩子則度為2的計數(shù)器加一,若該節(jié)點(diǎn)只有左孩子或只有右孩子,則度為1的結(jié)點(diǎn)數(shù)的計數(shù)器加一、(3) 在對其左右子樹進(jìn)行相同操作。偽碼算法:int *JudgeCBT(BiTree T)/統(tǒng)計不同度的結(jié)點(diǎn)數(shù)int static d3=0;/d1作為度為1的計數(shù)器,d2作為度為2的計數(shù)器if(T!=NULL)if(T-lchild!=NULL & T-rchild!=NULL)/左右孩子都有d2+;else/只有一個孩子if(T-lchild!=NULL & T-rchild=NULL)d1+;elseif(T-lchild=NULL & T-rchild!=NULL)d1+;JudgeCBT(T-lchild);/統(tǒng)計左子樹JudgeCBT(T-rchild);/統(tǒng)計右孩子return d;/返回數(shù)組的指針3)求非空子孫結(jié)點(diǎn)數(shù)算法描述:(1) 定義一個靜態(tài)局部變量,作為計數(shù)器;(2) 若該節(jié)點(diǎn)的左孩子非空則加一,右孩子非空亦加一;(3) 統(tǒng)計左子樹;統(tǒng)計右子樹。偽碼算法:int BiTreeDescendant(BiTree T)/統(tǒng)計非空子孫結(jié)點(diǎn)數(shù)int static n=0;/初始化計數(shù)器if(T!=NULL)if(T-lchild)n+;if(T-rchild)n+;BiTreeDescendant(T-lchild);/統(tǒng)計左子樹BiTreeDescendant(T-rchild);/統(tǒng)計右子樹return n;4)查找二叉樹的某個位置的結(jié)點(diǎn)(先序序列)算法描述:(1) 定義一個靜態(tài)局部變量,用作記錄已查結(jié)點(diǎn)的個數(shù);(2) 從根節(jié)點(diǎn)開始,如果相查找的位置理由元素,則打印該元素,如果想查的位置超過二叉樹本身的元素數(shù)則返回出錯。偽碼算法:int PreOderKNode(BiTree T,int k,TElemType *e)/T為二叉樹,k為帶查找的結(jié)點(diǎn)位序;e為指針帶值返回查找到的數(shù)。int static count=0;/作為計數(shù)器,記錄已查找的結(jié)點(diǎn)數(shù)if(T=NULL)return 0;count+;/訪問結(jié)點(diǎn),對已訪問的結(jié)點(diǎn)進(jìn)行計數(shù)if(count=k)/判斷該結(jié)點(diǎn)是否是待查找的結(jié)點(diǎn)e=&T-data;printf(存在你想查找位置的元素,先序序列中第%d個元素是%cn,k,*e);return 1;/查找成功elseif(countk)/計數(shù)器count已經(jīng)超出k,則直接返回0,查找不成功return 0;else/在左或右子樹中查找if(PreOderKNode(T-lchild,k,e)=0)return PreOderKNode(T-rchild,k,e);return 1;6、主程序的偽碼算法:void main()BiTree T=NULL,T_1=NULL,T_2=NULL;int i=1,*n=0,*kd,k=0; char x=0;printf(請按先序序列輸入各結(jié)點(diǎn)n);T=CreateBiTree(T);/先序序列構(gòu)造一棵二叉樹 /遍歷二叉樹printf(先序遍歷二叉樹:n);PreOderTraverse(T);putchar(n);printf(中序遍歷二叉樹:n);InOderTraverse(T);putchar(n);printf(后序遍歷二叉樹:n);PostOderTraverse(T);putchar(n);printf(層次遍歷二叉樹:n);LevelTraverse(T);putchar(n);printf(以廣義表形式打印二叉樹:n);/廣義表形式打印二叉樹print(T);putchar(n); /二叉樹的基本操作和運(yùn)算printf(二叉樹的葉子數(shù)LeafNumber為:%dn,LeafNum(T);/統(tǒng)計葉子數(shù)printf(二叉樹的深 度Depth為:%dn,BiTreeDepth(T);/計算深度printf(二叉樹的寬 度Width為:%dn,BiTreeWidth(T,i);/計算寬度 /統(tǒng)計非空子孫結(jié)點(diǎn)數(shù)printf(二叉樹非空子孫結(jié)點(diǎn)DescendantNumber數(shù)為:%dn,BiTreeDescendant(T);kd=JudgeCBT(T);/統(tǒng)計不同度的結(jié)點(diǎn)數(shù)printf(二叉樹度為1的結(jié)點(diǎn)數(shù)為:%d,度為2的結(jié)點(diǎn)數(shù)為:%dn,kd1,kd2); /二叉樹的基本操作,刪除和查找printf(下面進(jìn)行二叉數(shù)的查找和刪除操作n);T_2=CopyTree(T);putchar(n);/運(yùn)用二叉樹的復(fù)制操作printf(復(fù)制后的T_2,以先序序列輸出:n);PreOderTraverse(T_2);putchar(n);printf(請輸入你想查找在在先序序列的第幾個位置的元素n);scanf(%d,&k);if(!PreOderKNode(T_2,k,e)printf(不存在你想查找的位置n);T_1=CopyTree(T);putchar(n);printf(復(fù)制后的T_1,以先序序列輸出:n); PreOderTraverse(T_1);putchar(n);getchar();printf(請輸入你想刪除元素值為多少的結(jié)點(diǎn)n);x=getchar();getchar();DeleteXTree(T_1,x);printf(先序遍歷二叉樹:n); PreOderTraverse(T_1);putchar(n);printf(以廣義表形式打印二叉樹:n);print(T_1);putchar(n);四、 調(diào)試分析1、 在調(diào)試過程中,在進(jìn)行二叉樹的基本操作時就出現(xiàn)錯誤了,為了方便檢查錯誤,故逐漸將主函數(shù)的謀部分調(diào)用的函數(shù)先屏蔽后,再運(yùn)行調(diào)試,才發(fā)現(xiàn)了錯誤。2、 在調(diào)試過程中,為了方便對調(diào)用函數(shù)的檢查,每當(dāng)計數(shù)器變化時,就輸出該值,就可以看出是哪里的問題。3、 在調(diào)試過程中,在運(yùn)行刪除時,程序出現(xiàn)錯誤,當(dāng)輸入欲刪除結(jié)點(diǎn)后,程序并沒有刪除該結(jié)點(diǎn)。后來經(jīng)過調(diào)試才發(fā)現(xiàn),因為在輸入刪除元素時,是由getchar()接收,而在查找時遺留下的回車直接被getchar()接收,當(dāng)作NULL去運(yùn)行了。4、 在調(diào)試過程中,更改了4的錯誤,在刪除一個結(jié)點(diǎn)后,雖然能刪除元素了,但再次打印該樹后,就發(fā)現(xiàn)每當(dāng)打印到刪除結(jié)點(diǎn)位置時,程序就報錯。后來經(jīng)過老師和同學(xué)的幫助才發(fā)現(xiàn),雖然將待刪結(jié)點(diǎn)的空間釋放,但并沒有把指向該結(jié)點(diǎn)的父結(jié)點(diǎn)的指針域賦空,后來更改后,程序完美運(yùn)行了。5、 從程序?qū)嶒烆}的編制過程中容易看出,線性表的廣泛應(yīng)用,特別是順序存儲結(jié)構(gòu)的隊列和鏈?zhǔn)酱鎯Y(jié)構(gòu)的二叉樹的應(yīng)用。五、 用戶使用說明1、 本程序的運(yùn)行環(huán)境為Windows7旗艦版操作系統(tǒng),執(zhí)行文件為:二叉樹的基本操作及運(yùn)算.exe;2、 進(jìn)入程序后即顯示提示信息:“請按先序序列輸入各結(jié)點(diǎn)”以等待用戶輸入欲構(gòu)造的二叉樹的各元素值;若用戶輸入的的是一個不符合先序序列的字符串,則程序報錯;3、 在用戶正確輸入二叉樹的元素后,程序會自動對其先序、中序、后序和層次遍歷,并對二叉樹進(jìn)行求葉子數(shù)、深度、寬度、非空子孫結(jié)點(diǎn)數(shù)、度為1的結(jié)點(diǎn)數(shù)和度為2的結(jié)點(diǎn)數(shù)。并在自動復(fù)制一棵樹后,出現(xiàn)“請輸入你想查找在先序序列的第幾個位置的元素”,等待用戶輸入欲查找的元素位置;4、 輸入查找的位置后,如果存在該位置的元素,則程序會顯示“存在你想查找位置的元素,先序序列中第x個元素是x”;然后會彈出“請輸入你想刪除元素值為多少的結(jié)點(diǎn)”,等待用戶輸入某個元素值;5、 輸入某個元素值后,若刪除成功則會先序遍歷和廣義表形式打印刪除后的二叉樹。6、 本程序要求在輸入二叉樹元素是一定要正確,空格不能少,也不能多,不然程序會報錯。六、 測試結(jié)果1、 正確輸入:ABCDEGF,查找5,刪除E運(yùn)行界面:2、 正確輸入:ABDEHCFG (以表示空格),查找10,刪除B運(yùn)行界面:以上結(jié)果與自己在進(jìn)行程序概要分析時的預(yù)測結(jié)果一致七、 心得體會這次實驗設(shè)計讓我更加了解并更加靈活運(yùn)用到大一學(xué)到的C程序設(shè)計和這個學(xué)期學(xué)到的數(shù)據(jù)結(jié)構(gòu)。實驗任務(wù)要求不僅要求對課本知識有較深刻的了解,同時要求程序設(shè)計者有較強(qiáng)的思維和動手能力和更加了解編程思想和編程技巧。這次實驗設(shè)計讓我有一個深刻的體會,那就是細(xì)節(jié)決定成敗,編程最需要的是嚴(yán)謹(jǐn),如何的嚴(yán)謹(jǐn)都不過分,往往檢查了半天發(fā)現(xiàn)錯誤發(fā)生在某個括號,分號,引號,或者數(shù)據(jù)類型上。在進(jìn)行編程時一定要把每個問題都分析清楚,比如自己在編寫刪除刪除BiTree DeleteBiTree(BiTree t),BiTree DeleteXTree(BiTree t,TElemType x)時,只是把一個指針忘記賦為空,則導(dǎo)致程序報錯,希望以后在運(yùn)用遞歸調(diào)用時,一定要弄清各種值的傳遞關(guān)系。還有,在編寫函數(shù)時,編寫時能把每一步的結(jié)果都打印出來,這能很方便的調(diào)試程序。在編寫實驗報告時自己無意發(fā)現(xiàn),其實統(tǒng)計非空子孫結(jié)點(diǎn)數(shù)、不同度的結(jié)點(diǎn)數(shù)甚至葉子數(shù)的函數(shù)思想與算法十分相似,都可以編寫在一個函數(shù)里,這也說明了實驗報告的重要性,我們應(yīng)該在實驗報告里多反思、總結(jié),盡量完善自己的程序設(shè)計。 程序設(shè)計時,也不要怕遇到錯誤,在實際操作過程中犯的一些錯誤還會有意外的收獲,感覺課程設(shè)計很有意思。在具體操作中這學(xué)期所學(xué)的數(shù)據(jù)結(jié)構(gòu)的理論知識得到鞏固,達(dá)到課程設(shè)計的基本目的,也發(fā)現(xiàn)自己的不足之出,在以后的上機(jī)中應(yīng)更加注意,同時體會到C語言具有的語句簡潔,使用靈活,執(zhí)行效率高等特點(diǎn)。發(fā)現(xiàn)上機(jī)的重要作用,特別算術(shù)表達(dá)式有了深刻的理解。最后,感謝老師在這次課程設(shè)計的悉心指導(dǎo),祝老師身體健康,工作順利。參考文獻(xiàn):1.數(shù)據(jù)結(jié)構(gòu)(C語言版) 嚴(yán)蔚敏 清華大學(xué)出版社 2.C程序設(shè)計 譚浩強(qiáng) 清華大學(xué)出版社 3.數(shù)據(jù)結(jié)構(gòu)題集(C語言版)嚴(yán)蔚敏 吳偉民 米寧 清華大學(xué)出版社 4.C程序設(shè)計學(xué)習(xí)指導(dǎo)與練習(xí)賈伯琪 中國科學(xué)技術(shù)大學(xué)出版社八、 附錄“二叉樹的基本操作及運(yùn)算”源程序代碼:#include#include#includetypedef char TElemType;char *e;#define M 10typedef struct BiTNodeTElemType data;struct BiTNode *lchild,*rchild;BiTNode,*BiTree;typedef struct QNodeBiTree data;struct QNode *next;QNode,*Queueptr;typedef structQueueptr front;Queueptr rear;LinkQueue;void InitQueue(LinkQueue *Q)Q-front=Q-rear=(Queueptr)malloc(sizeof(QNode);if(!Q-front)exit(1);Q-front-next=NULL;void EnQueue(LinkQueue *Q,BiTree e)Queueptr q;q=(Queueptr)malloc(sizeof(QNode);if(!q)exit(1);q-data=e;q-next=NULL;Q-rear-next=q;Q-rear=q;BiTree DeQueue(LinkQueue *Q)Queueptr p;BiTree q;if(Q-front=Q-rear)printf(ERROR!n);exit(1);p=Q-front-next;q=p-data;Q-front-next=p-next;if(Q-rear=p)Q-rear=Q-front;free(p);return q;int QueueEmpty(LinkQueue *Q)if(Q-front=Q-rear)return 1;elsereturn 0;BiTree CreateBiTree(BiTree T)char ch;if(ch=getchar()= )T=NULL;elseif(ch!=n)if(!(T=(BiTree)malloc(sizeof(BiTNode)exit(1);T-data=ch;T-lchild=CreateBiTree(T-lchild);T-rchild=CreateBiTree(T-rchild);return T;void PreOderTraverse(BiTree T)if(T)putchar(T-data);PreOderTraverse(T-lchild);PreOderTraverse(T-rchild);void InOderTraverse(BiTree T)if(T)InOderTraverse(T-lchild);putchar(T-data);InOderTraverse(T-rchild);void PostOderTraverse(BiTree T)if(T)PostOderTraverse(T-lchild);PostOderTraverse(T-rchild);putchar(T-data);int visit(TElemType e)if(e)putchar(e);return 1;elsereturn 0;void LevelTraverse(BiTree T)LinkQueue *Q=(LinkQueue *)malloc(sizeof(LinkQueue);BiTree p=(BiTree)malloc(sizeof(BiTNode);InitQueue(Q);if(T!=NULL)if(!visit(T-data)exit(1);EnQueue(Q,T);while(!QueueEmpty(Q)p=DeQueue(Q);if(p-lchild!=NULL)if(!visit(p-lchild-data)exit(1);EnQueue(Q,p-lchild);if(p-rchild!=NULL)if(!visit(p-rchild-data)exit(1);EnQueue(Q,p-rchild);int BiTreeDepth(BiTree T)int hl=0,hr=0;if(!T)return 0;elsehl=BiTreeDepth(T-lchild);hr=BiTreeDepth(T-rchild);if(hl=hr)return hl+1;else return hr+1;int BiTreeWidth(BiTree T,int i)int static nM=0;int static max=0;if(T!=NULL)if(i=1)ni+;i+;if(T-lchild)ni+;if(T-rchild)ni+;elsei+;if(T-lchild)ni+;if(T-rchild)ni+;if(maxlchild,i);BiTreeWidth(T-
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 發(fā)電機(jī)采購安裝合同
- 放射衛(wèi)生監(jiān)測設(shè)備采購合同
- 拆遷房屋轉(zhuǎn)讓協(xié)議
- 商品種類及銷售情況對比表
- 陸豐市經(jīng)貿(mào)局學(xué)習(xí)實踐科學(xué)發(fā)展觀活動第三階段工作方案
- 教師三筆字活動方案
- 2025年中儲糧集團(tuán)紀(jì)檢監(jiān)察組招聘(4人)筆試參考題庫附帶答案詳解
- 2025寧夏天元錳業(yè)集團(tuán)有限公司招聘11崗6596人筆試參考題庫附帶答案詳解
- 2025國網(wǎng)電力工程研究院有限公司高校畢業(yè)生招聘(第一批)筆試參考題庫附帶答案詳解
- 2025年上半年宜賓市翠屏區(qū)事業(yè)單位招考高層次和緊缺專業(yè)高校畢業(yè)生易考易錯模擬試題(共500題)試卷后附參考答案
- 2025年江西青年職業(yè)學(xué)院高職單招職業(yè)技能測試近5年??及鎱⒖碱}庫含答案解析
- 初中物理校本教材《物理之窗》內(nèi)容
- 清華大學(xué)考生自述
- 煙草專賣執(zhí)法人員考試案例分析題庫
- 最新地鐵通信系統(tǒng)首件定標(biāo)籌劃
- 企業(yè)工資集體協(xié)商流程圖
- 涌水突泥培訓(xùn)試題
- DB33_T 2352-2021鄉(xiāng)鎮(zhèn)運(yùn)輸服務(wù)站設(shè)置規(guī)范(可復(fù)制)
- 《紅樓夢 - 林黛玉進(jìn)賈府》PPT課件(教學(xué))
- 【新教材】高中語文超全課內(nèi)知識梳理(選擇性必修中冊)
- 血?dú)夥治雠R床基礎(chǔ)(課堂PPT)
評論
0/150
提交評論