資料結構與演算法·實驗十
1.構造一棵二叉樹,樹的形態如下圖所示,打印出前序遍歷、中序遍歷、後序遍歷的遍歷序列。
2.選擇一種遍歷方式計算該樹中葉子結點的個數,並打印出葉子結點。
3.編寫一個查詢演算法,查詢資料“E”是否存在。
#include"stdlib.h" #include"stdio.h" typedef char DataType; #include"BiTree.h" #define MaxStackSize 100 /*typedef char ElemType;*/ typedef BiTreeNode* ElemType; #include "SeqStack.h" #include "LinQueue.h" void main() { BiTreeNode *root; Initiate(&root); if(root!=NULL) root=createbintree(); printf("先序遍歷:"); PreOrder(root,visit); //先序遍歷 printf("\n"); printf("中序遍歷:"); InOrder(root,visit); //中序遍歷 printf("\n"); printf("後序遍歷:"); PostOrder(root,visit); //後序遍歷 printf("\n"); printf("二叉樹中結點個數為:%d\n",numofnode(root)); printf("二叉樹中葉子結點個數為:%d\n",preleafnum(root)); printf("\n/**************************************************************************************/\n\n"); LayerOrder(root); printf("非遞迴先序遍歷:"); PreOrderByStack(root); printf("非遞迴中序遍歷:"); InOrderByStack(root); printf("佇列結構層序遍歷為:"); LayerOrder2(root); printf("\n"); Destroy(&root); }
typedef struct Node { DataType data; /*資料域*/ struct Node *leftChild; /*左子樹指標*/ struct Node *rightChild; /*右子樹指標*/ }BiTreeNode; /*結點的結構體定義*/ void Initiate(BiTreeNode **root) /*初始化建立二叉樹的頭結點*/ { *root=(BiTreeNode *)malloc(sizeof(BiTreeNode)); (*root)->leftChild=NULL; (*root)->rightChild=NULL; } void Destroy(BiTreeNode **root) { if((*root)!=NULL&&(*root)->leftChild!=NULL) Destroy(&(*root)->leftChild); if((*root)!=NULL&&(*root)->rightChild!=NULL) Destroy(&(*root)->rightChild); free(*root); } /*若當前結點curr非空,在curr的左子樹插入元素值為x的新結點*/ /*原curr所指結點的左子樹成為新插入結點的左子樹*/ /*若插入成功返回新插入結點的指標,否則返回空指標*/ BiTreeNode *InsertleftNode(BiTreeNode *curr,DataType x) { BiTreeNode *s,*t; if(curr==NULL) return NULL; t=curr->leftChild; s=(BiTreeNode *)malloc(sizeof(BiTreeNode)); s->data=x; s->leftChild=t; s->rightChild=NULL; curr->leftChild=s; return curr->leftChild; } BiTreeNode *InsertRightNode(BiTreeNode *curr,DataType x) { BiTreeNode *s,*t; if(curr==NULL) return NULL; t=curr->rightChild; /*儲存原curr所指結點的右子樹指標*/ s=(BiTreeNode *)malloc(sizeof(BiTreeNode)); s->data=x; s->rightChild=t; /*新插入結點的右子樹為原curr的右子樹*/ s->leftChild=NULL; curr->rightChild=s; /*新結點成為curr的右子樹*/ return curr->rightChild; /*返回新插入結點的指標*/ } BiTreeNode *DeleteLeftTree(BiTreeNode *curr) /*若curr非空,刪除curr所指結點的左子樹*/ { if(curr==NULL||curr->leftChild==NULL) return NULL; Destroy(&curr->leftChild); curr->leftChild=NULL; return curr; /*若刪除成功返回刪除結點的雙親結點指標,否則返回空指標*/ } BiTreeNode *DeleteRightTree(BiTreeNode *curr) { if(curr==NULL||curr->rightChild==NULL) return NULL; Destroy(&curr->rightChild); curr->rightChild=NULL; return curr; } void PreOrder(BiTreeNode *t,void visit(DataType item)) { if(t!=NULL) { visit(t->data); PreOrder(t->leftChild,visit); PreOrder(t->rightChild,visit); } } void InOrder(BiTreeNode *t,void visit(DataType item)) { if(t!=NULL) { InOrder(t->leftChild,visit); visit(t->data); InOrder(t->rightChild,visit); } } void PostOrder(BiTreeNode *t,void visit(DataType item)) { if(t!=NULL) { PostOrder(t->leftChild,visit); PostOrder(t->rightChild,visit); visit(t->data); } } void visit(DataType item) { printf("%c",item); } void visit2(BiTreeNode *t) { printf("%c",t->data); } BiTreeNode *createbintree(void) { BiTreeNode *pbnode; char ch; scanf("%c",&ch); if(ch=='#') pbnode=NULL; else { pbnode=(BiTreeNode *)malloc(sizeof(BiTreeNode)); if(pbnode==NULL) return pbnode; //InsertleftNode(pbnode,ch); pbnode->data=ch; pbnode->leftChild=createbintree(); pbnode->rightChild=createbintree(); } return pbnode; } int numofnode(BiTreeNode *t) { if(t==NULL) return 0; else return(numofnode(t->leftChild)+numofnode(t->rightChild)+1); } int preleafnum(BiTreeNode *t) { if(t==NULL) return 0; else { if((t->leftChild==NULL)&&(t->rightChild==NULL)) { return 1; } return preleafnum(t->leftChild)+preleafnum(t->rightChild); } } /*int locate(BiTreeNode *t,DataType x) { BiTreeNode *p; if(t==NULL) return 0; if(t->data==x) return 1; else { p=locate(t->leftChild,x); if(p) return 1; else return locate(t->rightChild,x); } }*/ void LayerOrder(BiTreeNode *T) { int front=0,rear=1; BiTreeNode *a[100]; a[0]=T; printf("非佇列結構層序遍歷為:"); while(front<rear) { if(a[front]) { printf("%c",a[front]->data); if(a[front]->leftChild!=NULL) { a[rear++]=a[front]->leftChild; } if(a[front]->rightChild!=NULL) { a[rear++]=a[front]->rightChild; } front++; } else { front++; } } printf("\n"); } BiTreeNode *leftchild(BiTreeNode *p) { if(p==NULL) return NULL; return p->leftChild; } BiTreeNode *rightchild(BiTreeNode *p) { if(p==NULL) return NULL; return p->rightChild; }
typedef struct qnode { ElemType data; struct qnode *next; }LQNode; typedef struct { LQNode *front; /*隊頭指標*/ LQNode *rear; /*隊尾指標*/ }LQueue; void QueueInitiate(LQueue *Q) /*初始化鏈式佇列Q*/ { Q->rear=NULL; /*定義初始隊尾指標下標值*/ Q->front=NULL; /*定義初始隊頭指標下標值*/ } int QueueNotEmpty(LQueue Q) /*判鏈式佇列Q非空否,非空則返回1,否則返回0*/ { if(Q.front==NULL) return 0; else return 1; } int QueueAppend(LQueue *Q,ElemType x) /*把資料元素值x插入鏈式佇列Q的隊尾,入佇列成功則返回1,否則返回0 */ { LQNode *p; if((p=(LQNode *)malloc(sizeof(LQNode)))==NULL) { printf("記憶體空間不足!"); return 0; } p->data=x; p->next=NULL; if(Q->rear!=NULL) Q->rear->next=p; Q->rear=p; if(Q->front==NULL) Q->front=p; return 1; } int QueueDelete(LQueue *Q,ElemType *d) /*刪除鏈式佇列Q的隊頭資料元素值到d ,出佇列成功則返回1,否則返回0*/ { LQNode *p; if(Q->front==NULL) { printf("佇列已空無資料元素出佇列!\n"); return 0; } else { *d=Q->front->data; p=Q->front; Q->front=Q->front->next; if(Q->front==NULL) Q->rear=NULL; free(p); return 1; } } int QueueGet(LQueue Q,ElemType *d) /*取鏈式佇列Q的當前隊頭資料元素值到d ,成功則返回1,否則返回0*/ { if(Q.front==NULL) { printf("佇列已空無資料元素出佇列!\n"); return 0; } else { *d=Q.front->data; return 1; } } void Destroy1(LQueue Q) { LQNode *p,*p1; p=Q.front; while(p!=NULL) { p1=p; p=p->next; free(p1); } } void LayerOrder2(BiTreeNode *T) { LQueue myQueue; BiTreeNode *Q; /*Initiate(&Q);*/ QueueInitiate(&myQueue); QueueAppend(&myQueue,T); while(QueueNotEmpty(myQueue)==1) { QueueDelete(&myQueue,&Q); visit2(Q); if(Q->leftChild!=NULL) QueueAppend(&myQueue,Q->leftChild); if(Q->rightChild!=NULL) QueueAppend(&myQueue,Q->rightChild); } }
typedef struct
{
ElemType stack[MaxStackSize];
int top;
}SeqStack;
void StackInitiate(SeqStack *S) /*初始化順序堆疊S*/
{
S->top=0; /*定義初始棧頂下標值*/
}
int StackNotEmpty(SeqStack S) /*判順序堆疊S非空否,非空則返回1,否則返回0*/
{
if(S.top<=0)
return 0;
else return 1;
}
int StackPush(SeqStack *S,ElemType x) /*把資料元素值x壓入順序堆疊S,入棧成功則返回1,否則返回0 */
{
if(S->top>=MaxStackSize)
{
printf("堆疊已滿無法插入!\n");
return 0;
}
else
{
S->stack[S->top]=x;
S->top++;
return 1;
}
}
int StackPop(SeqStack *S,ElemType *d) /*彈出順序堆疊S的棧頂資料元素值到引數d ,出棧成功則返回1,否則返回0*/
{
if(S->top<=0)
{
printf("堆疊已空無法插入!\n");
return 0;
}
else
{
S->top--;
*d=S->stack[S->top];
return 1;
}
}
int StackTop(SeqStack S,ElemType *d) /*取順序堆疊S的當前棧頂資料元素值到引數d ,成功則返回1,否則返回0*/
{
if(S.top<=0)
{
printf("堆疊已空!\n");
return 0;
}
else
{
*d=S.stack[S.top-1];
return 1;
}
}
void PreOrderByStack(BiTreeNode *root)
{
SeqStack s;
BiTreeNode *p=root;
StackInitiate(&s);
while(StackNotEmpty(s)||p) //StackNotEmpty(SeqStack S)
{
if(p)
{
visit2(p);
StackPush(&s,p); //StackPush(SeqStack *S,DataType x)
p=leftchild(p);
}
else
{
StackPop(&s,&p); //StackPop(SeqStack *S,DataType *d)
p=rightchild(p);
}
}
printf("\n");
}
void InOrderByStack(BiTreeNode *root)
{
SeqStack s;
BiTreeNode *p=root;
StackInitiate(&s);
while(StackNotEmpty(s)||p) //StackNotEmpty(SeqStack S)
{
if(p)
{
//visit(p);
StackPush(&s,p); //StackPush(SeqStack *S,DataType x)
p=leftchild(p);
}
else
{
StackPop(&s,&p); //StackPop(SeqStack *S,DataType *d)
visit2(p);
p=rightchild(p);
}
}
printf("\n");
}
相關推薦
資料結構與演算法·實驗十
1.構造一棵二叉樹,樹的形態如下圖所示,打印出前序遍歷、中序遍歷、後序遍歷的遍歷序列。 2.選擇一種遍歷方式計算該樹中葉子結點的個數,並打印出葉子結點。 3.編寫一個查詢演算法,查詢資料“E”是否存在。 #include"stdlib.h" #include"stdio
Python-資料結構與演算法(十一、字典(對映)——基於兩種不同的底層實現)
保證一週更兩篇吧,以此來督促自己好好的學習!程式碼的很多地方我都給予了詳細的解釋,幫助理解。好了,幹就完了~加油! 宣告:本python資料結構與演算法是imooc上liuyubobobo老師java資料結構的python改寫,並添加了一些自己的理解和新的東西,liuyubobobo
資料結構與演算法之十 提高二叉搜尋樹的效率
/*寫一個程式以實現插入、刪除且遍歷線索二叉搜尋樹,這裡樹中的每個節點包含一個字典程式。*/ using System; using System.Text; namespace Threads { class Node { /*兩個線索域;lthread,rthread;1
資料結構與演算法·實驗三
1、利用順序棧將一個非負的十進位制整數N轉換為對應的B進位制數。 要求:非負的十進位制整數N和B都從鍵盤輸入;轉換結果從螢幕輸出。 2、括號匹配問題,編寫一個判別表示式中括號是否正確配對的函式,並設計一個測試主函式。 #include<stdio.h>
資料結構與演算法(十二)並查集(Union Find)
本文主要包括以下內容: 並查集的概念 並查集的操作 並查集的實現和優化 Quick Find Quick Union 基於size的優化 基於rank的優化 路徑壓縮優化 並查集的時間複雜度 並查集的概念 在電腦科學中,並查集 是一種樹形的資料結
資料結構與演算法之十一 圖
視訊課堂https://edu.csdn.net/course/play/7621 目標. 在本章中,你將學習到: 圖相關的概念 實現圖 應用圖解決程式設計問題
資料結構與演算法實驗題 素數區間
★實驗任務 dark di 在做數學題目的時候發現了一個現象,2 個相鄰的素數之間存在一 個區間,他把這個區間稱為非素數區間,那麼 dark di 想知道,給定一個正整數 x,x 所在的非素數區間長度是多少呢? 例如 23 和 29 是 2 個相鄰的素數,他們之
資料結構與演算法 (十) 二叉樹 前序遍歷 中序遍歷 後序遍歷
名詞解釋 度數(degree) 一個結點的子樹個數 樹葉(leaf) 沒有子樹的結點稱為樹葉或終端結點 分支結點(branch node) 非終端結點 子女(child)和兒子(son)非終端結點 父母(parent)若
資料結構與演算法(十)
連結串列的操作(遍歷、查詢、清空、銷燬、求長度、增加、刪除) 建立一個連結串列:需要三個指標(頭指標、始終指向尾節點的指標(剛開始讓其指向頭結點)、新創節點指標) 遍歷:需要一個指標P,剛開始指向首節點,用while(NULL!=P)來迴圈,在迴圈裡面更新指標P,P = P->pNex
資料結構與演算法·實驗九
求二叉樹的層序遍歷問題 要求:(1)編寫一個建立二叉樹的函式。 (2)編寫按層次(同一層自左至右)輸出二叉樹中所有的結點的函式。 (3)編寫一個測試主函式。 #include<stdlib.h> #include<stdio.h&
資料結構與演算法(十)線段樹(Segment Tree)入門
本文主要包括以下內容: 線段樹的概念 線段樹的基本操作 實現一個線段樹 LeetCode相關線段樹的問題 線段樹的概念 線段樹(Segment Tree)也是一棵樹,只不過元素的值代表一個區間。 常用區間的 統計 操作,比如一個區間的最大值(ma
哈工大資料結構與演算法實驗4
實驗要求 寫一個快速排序演算法,實現資料的快速排序 思路 隨便網上都能找到快排演算法,然後照抄就ok。。。當然理解快排是必要的,只是快排不是很好理解,詳情請百度 #include <i
資料結構與演算法(十一)Trie字典樹
本文主要包括以下內容: Trie字典樹的基本概念 Trie字典樹的基本操作 插入 查詢 字首查詢 刪除 基於連結串列的Trie字典樹 基於Trie的Set效能對比 LeetCode相關線段樹的問題 LeetCode第208號問題 LeetCode第211
為什麼我要放棄javaScript資料結構與演算法(第十章)—— 排序和搜尋演算法
本章將會學習最常見的排序和搜尋演算法,如氣泡排序、選擇排序、插入排序、歸併排序、快速排序和堆排序,以及順序排序和二叉搜尋演算法。 第十章 排序和搜尋演算法 排序演算法 我們會從一個最慢的開始,接著是一些效能好一些的方法 先建立一個數組(列表)來表示待排序和搜尋的資料結構。 function Arra
為什麼我要放棄javaScript資料結構與演算法(第十一章)—— 演算法模式
本章將會學習遞迴、動態規劃和貪心演算法。 第十一章 演算法模式 遞迴 遞迴是一種解決問題的方法,它解決問題的各個小部分,直到解決最初的大問題。遞迴通常涉及函式呼叫自身。 遞迴函式是像下面能夠直接呼叫自身的方式或函式 function recursiveFunction(someParam){
買什麼資料結構與演算法,這裡有:動態圖解十大經典排序演算法(含JAVA程式碼實現)
上篇的動圖資料結構反響不錯,這次來個動圖排序演算法大全。資料結構與演算法,齊了。 幾張動態圖捋清Java常用資料結構及其設計原理 本文將採取動態圖+文字描述+正確的java程式碼實現來講解以下十大排序演算法: 氣泡排序 選擇排序 插入排序 希爾排序
【資料結構與演算法】之紅黑樹 --- 第十四篇
樹是一種非線性資料結構,這種資料結構要比線性資料結構複雜的多,因此分為三篇部落格進行講解: 第一篇:樹的基本概念及常用操作的Java實現(二叉樹為例) 第二篇:二叉查詢樹 第三篇:紅黑樹 第三篇:紅黑樹 開篇說明:對於紅黑樹的學習,近階段只需要掌握這種資料結構的思想、特點、適
【資料結構與演算法】之樹的基本概念及常用操作的Java實現(二叉樹為例) --- 第十二篇
樹是一種非線性資料結構,這種資料結構要比線性資料結構複雜的多,因此分為三篇部落格進行講解: 第一篇:樹的基本概念及常用操作的Java實現(二叉樹為例) 第二篇:二叉查詢樹 第三篇:紅黑樹 本文目錄: 1、基本概念 1.1 什麼是樹 1.2 樹的
《資料結構與演算法A》實驗1:按資料元素升序建立單鏈表
** 實驗題目 ** 對輸入的正整數序列建立有序單鏈表。在建立單鏈表的過程中,連結串列中的資料元素按升序排列。當輸入的資料元素在單鏈表中已經存在時,不進行插入操作。 請使用面向物件形式定義結點類和連結串列類,參考程式碼如下。 class Node { int
《資料結構與演算法A》實驗2:棧的應用
題目: Description 根據棧的特點,實現十進位制到其他進位制之間的轉換,具體要求如下: (1)利用棧進行十進位制數與N進位制(如二進位制、八進位制、十六進位制)資料之間的轉換; (2)通過順序棧記錄進位制轉換的中間結果,該順序棧有一個指示棧頂的變數top,