日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

《数据结构与算法》实验报告——二叉树的遍历

發布時間:2024/10/5 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《数据结构与算法》实验报告——二叉树的遍历 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

《數據結構》實驗報告

?

學號:? 2018329621200? ?

機房號? 10-414??

姓名:?? 申屠志剛??

日期:???? 2019/11/4?????

程序名:??????? main.cpp??????????

實驗內容:?? 二叉樹的遍歷??????

一、目的和要求(需求分析):

1、掌握二叉樹的存儲結構以及二叉樹的建立和操作

2、輸入一串表達式后,建立二叉樹,并對其進行先序、中序和后序的遍歷。

(輸入表達式如此形式:a+b*c-d-e/f….;以#號結束。)

3、遞歸實現表達式運算。

?

二、程序設計的基本思想,原理和算法描述:

1、輸入中綴表達式;

2、中綴表達式轉化后綴表達式;

3、后綴表達式轉化后綴表達式樹;

4、遞歸實現表達式運算。

三、調試和運行程序過程中產生的問題及采取的措施:

1、中綴表達式建立表達式樹比較繁瑣;

措施:中綴表達式先轉化后綴表達式;

2、判斷存在括號的情況;

措施:利用棧;

3、多位數字的情況;

措施:atof函數。

四、源程序及注釋:

Main.cpp

/* *@Author: STZG *@Language: C++ */ #include <stdio.h> #include <stdlib.h> #include <iostream> #include <string> #include <cstring> #include <algorithm> using namespace std; #define MAX 100//樹結點的設計 typedef struct node {//數字和運算符union{char op;int data;};struct node *lchild;struct node *rchild;}TreeNode;//樹棧的設計 typedef struct {TreeNode *buf[MAX];int n;}TreeStack;//創建空棧 TreeStack *create_empty_stack() {TreeStack *pstack;pstack = (TreeStack *)malloc(sizeof(TreeStack));pstack->n = -1;return pstack; }//入棧 int push_stack(TreeStack *p,TreeNode *data) {p->n ++;p->buf[p->n] = data;return 0; }//出棧 TreeNode *pop_stack(TreeStack *p) {TreeNode *data;data = p->buf[p->n];p->n --;return data; }//判斷空棧 int is_empty_stack(TreeStack *p) {if(p->n == -1){return 1;}else{return 0;} }//后綴表達式樹的創建 TreeNode *create_express_tree(char *str,TreeStack *p) {int i = 0;char dst[100];TreeNode *current;TreeNode *left,*right;int len=strlen(str);while(str[i]){if(str[i] == ' '){i ++;continue;}if(isdigit(str[i])){sscanf(str+i,"%s",dst);current = (TreeNode *)malloc(sizeof(TreeNode));current->data = atof(dst);current->lchild = current->rchild = NULL;push_stack(p,current);while (i+1 < len && isdigit(str[i+1])){++i;}}else{current = (TreeNode *)malloc(sizeof(TreeNode));current->op = str[i];right = pop_stack(p);left = pop_stack(p);current->lchild = left;current->rchild = right;push_stack(p,current);}/*printf("%s\n",str);if(current!=NULL)printf("%d or %c\n",current->data,current->data);*/i ++;}return p->buf[p->n]; }//打印結點 void print_node(TreeNode *p) {if(p->lchild == NULL && p->rchild == NULL){printf("%d ",p->data);}else{printf("%c ",p->op);}return; }//訪問結點 int vist_node(TreeNode *p) {print_node(p);return 0; }//樹的后序遍歷 int PostOrder(TreeNode *p) {if(p != NULL){PostOrder(p->lchild);//左PostOrder(p->rchild);//右vist_node(p);//根}return 0; }//樹的中序遍歷 int InOrder(TreeNode *p) {if(p != NULL){InOrder(p->lchild);//左vist_node(p);//根InOrder(p->rchild);//右}return 0; }//樹的前序遍歷 int PreOrder(TreeNode *p) {if(p != NULL){vist_node(p);//根PreOrder(p->lchild);//左PreOrder(p->rchild);//右}return 0; }char stack[500]; //定義順序棧,其中top==0表示棧為空; int top; //棧頂指針,為0表示棧為空; char output[500], input[500]; //波蘭式 int outLen;int priority(char op) //判斷運算符級別函數;其中* /的級別為2,+ -的級別為1; {if (op=='+' || op=='-')return 1;if (op=='*' || op=='/')return 2;elsereturn 0; }bool isOperator(char op) //判斷輸入串中的字符是不是操作符,如果是返回true {return (op=='+' || op=='-' || op=='*' || op=='/'); }void rePolish(char *s,int len) //將一個中綴串轉換為后綴串, {memset(output,'\0',sizeof output); //輸出串outLen = 0;for (int i=0; i < len; ++i) //1)求輸入串的逆序。{if (isdigit(s[i])) //經驗見:http://blog.csdn.net/linraise/article/details/18566319#comments{output[outLen++] = s[i]; //3)假如是操作數,把它添加到輸出串中。while (i+1 < len && isdigit(s[i+1])){output[outLen++] = s[i+1];++i;}output[outLen++] = ' '; //空格隔開}if (s[i]=='(') //4)假如是閉括號,將它壓棧。{++top;stack[top] = s[i];}while (isOperator(s[i])) //5)如果是運算符,執行算法對應操作;{if (top==0 || stack[top]=='(' || priority(s[i]) > priority(stack[top])) //空棧||或者棧頂為)||新來的元素優先級更高{++top;stack[top] = s[i];break;}else{output[outLen++] = stack[top];output[outLen++] = ' ';--top;}}if (s[i]==')') //6)假如是開括號,棧中運算符逐個出棧并輸出,直到遇到閉括號。閉括號出棧并丟棄。{while (stack[top]!='('){output[outLen++] = stack[top];output[outLen++] = ' ';--top;}--top; // 此時stack[top]==')',跳過)}//7)假如輸入還未完畢,跳轉到步驟2。}while (top!=0) //8)假如輸入完畢,棧中剩余的所有操作符出棧并加到輸出串中。{output[outLen++] = stack[top];output[outLen++] = ' ';--top;} }double OP(double op1,double op2,char op) {double res = 0;if (op=='+')res = op1 + op2;else if (op=='-')res = op1 - op2;else if (op=='*')res = op1 * op2;else if (op=='/')res = op1 / op2;return res; }double cSt1[200]; //波蘭式的計算 double CalOrder(char *s) //波蘭式需要用兩個棧,逆波蘭式只需要一個棧 {char dst[80];int top1=0, i;for (i=0; s[i]; ++i){if (s[i] && s[i] != ' '){sscanf(s+i,"%s",dst);if (isdigit(dst[0])){++top1;cSt1[top1] = atof(dst); //進棧}else{cSt1[top1-1] = OP(cSt1[top1-1], cSt1[top1], dst[0]);// memcpy(cSt1[top1-1],DstBuf,sizeof DstBuf);--top1; //操作數棧:出棧倆,進棧一}while (s[i] && s[i] != ' ')++i;}}return cSt1[1]; } //樹的計算 double CalOrder(TreeNode *p) {if(p->lchild != NULL&&p->rchild != NULL){return OP(CalOrder(p->lchild) ,CalOrder(p->rchild), p->op);}return p->data; }int main() {TreeNode *thead;TreeStack *pstack;int i = 0;while((input[i++] = getchar()) != '\n' && i < 100);input[i-1] = 0;printf("%s\n",input);rePolish(input, strlen(input));output[outLen-1] = '\0';pstack = create_empty_stack();thead = create_express_tree(output,pstack);printf("PostOrder:: ");PostOrder(thead);printf("\n");printf("InOrder:: ");InOrder(thead);printf("\n");printf("PreOrder:: ");PreOrder(thead);printf("\n");printf("CalOrder::");printf("%f",CalOrder(output));printf("\n");printf("CalOrder::");printf("%f",CalOrder(thead));printf("\n");return 0; }

五、運行輸出結果:

六、心得與體會:

1、掌握二叉樹的存儲結構以及二叉樹的建立和操作。

2、輸入一串表達式后,建立二叉樹,并對其進行先序、中序和后序的遍歷。

3、遞歸實現表達式運算。

4、理論上來講, 一個中綴表達式是不能夠轉換出一個唯一的二叉樹的,但是中綴算術表達式因為有運算符的優先級關系, 建立二叉樹時, 需要所有的操作數都在葉子節點上, 所有的操作符都在父(根)節點上, 這個特征可以生成一個唯一的二叉樹。

5、atof函數的運用。

?

?

?

?

?

?

?

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的《数据结构与算法》实验报告——二叉树的遍历的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。