收藏 分销(赏)

数据结构实验报告树形数据结构实验.doc

上传人:人****来 文档编号:9768849 上传时间:2025-04-07 格式:DOC 页数:37 大小:190.54KB 下载积分:12 金币
下载 相关 举报
数据结构实验报告树形数据结构实验.doc_第1页
第1页 / 共37页
数据结构实验报告树形数据结构实验.doc_第2页
第2页 / 共37页


点击查看更多>>
资源描述
实验报告书 课程名: 数据结构 题 目: 树形数据结构实验(1) 班 级: 学 号: 姓 名: 评语: 成绩: 指导教师: 批阅时间: 年 月 日 35 / 37 一、目的与要求 1)熟练掌握二叉树的二叉链表表示创建算法与实现; 2)熟练掌握栈的前序、中序和后序递归遍历算法与实现; 3)熟练掌握前序、中序和后序遍历线索二叉树的基本算法与实现; 4)按照实验题目要求独立正确地完成实验内容(提交程序清单及相关实验数据与运行结果); 5)认真书写实验报告,并按时提交。 二、实验内容或题目 1) 创建二叉树:广义表式创建和先序创建; 2) 遍历二叉树:先,中,后,层序遍历,广义表式遍历,凹凸式遍历; 3) 二叉树属性:深度,宽度,结点数,叶子结点数 4) 二叉树路径:叶子结点到根结点的路径; 5)二叉树线索:中序线索二叉树; 6)二叉树置空:清空二叉树。 三、实验步骤与源程序 1)头文件Btree.h #include <iostream.h> #include <iomanip.h> #include <stdio.h> #include <stdlib.h> #include <time.h> /**********************************对象--二叉数**************** ****************/ typedef char ElemType; // 定义元素类型 #define MAXSIZE 100 // 确定二叉树的最大结点数 /******************************二叉数的结点类定义******************************/ class BTreeNode { private: int ltag,rtag; // 线索标记 BTreeNode *left; // 左子树指针 BTreeNode *right; // 右子树指针 public: ElemType data; // 数据域 // 构造函数 BTreeNode() { ltag=0; rtag=0; left=NULL; right=NULL; } // 带参数初始化的构造函数 BTreeNode(ElemType item,int ltag1,int rtag1,BTreeNode *left1,BTreeNode *right1) { data=item; ltag=ltag1; rtag=rtag1; left=left1; right=right1; } BTreeNode *&Left() // 返回结点的左孩子 { return left; } // 返回结点的右孩子 BTreeNode *&Right() { return right; } friend class BinaryTree; // 二叉树类为二叉树结点类的友元类 }; /**********************************二叉数的类定义*******************************/ class BinaryTree { private: BTreeNode *root; public: //构造函数.初始化二叉树为空 BinaryTree() { root=NULL; } // 判断二叉树是否为空 bool BTreeEmpty() { return root==NULL; } /****************************创建二叉数的相关成员函数***********************/ // 按照二叉树的广义表表示创建二叉树 void CreateBTree1(); // 递归创建二叉树,被函数CreateBTree1调用 void Create1(BTreeNode *&BT); // 按一定次序输入二叉树中结点的值(一个字符),空格表示空树 void CreateBTree2(int make); // 递归先序创建二叉树,被函数CreateBTree2调用 void Greate2(BTreeNode*&BT,int mark); // 复制二叉树 void BTreeCopy(BTreeNode *&root,BTreeNode *&BT); /****************************遍历二叉数的相关成员函数***********************/ // 按任一种遍历次序输出二叉树中的所有结点 void TraverseBTree(int mark); // 用于遍历的递归函数,被函数TraverseBTree调用 void Traverse(BTreeNode *&BT,int mark); // 先序遍历的递归函数 void PreOrder(BTreeNode *&BT); // 先序遍历的非递归函数一 void PreOrder_N1(BTreeNode *&BT); // 先序遍历的非递归函数二 void PreOrder_N2(BTreeNode *&BT); // 中序遍历的递归函数 void InOrder(BTreeNode *&BT); // 中序遍历的非递归函数一 void InOrder_N1(BTreeNode *&BT); // 中序遍历的非递归函数二 void InOrder_N2(BTreeNode *&BT); // 后序遍历的递归函数 void PostOrder(BTreeNode *&BT); // 后序遍历的非递归函数一 void PostOrder_N1(BTreeNode *&BT); // 后序遍历的递归函数 void PostOrder_N2(BTreeNode *&BT); // 层序遍历的非递归函数 void LayerOrder(BTreeNode *&BT); // 按照二叉树的广义表表示输出整个二叉树 void GPrintBTree(); // 广义表形式输出整个二叉树的递归函数,被函数Print调用 void GPrint(BTreeNode *&BT); // 以凹凸表示法输出二叉树 void OPrintTree(); /**********************************二叉树的属性*****************************/ /****************计算二叉数深度,宽度,叶子,结点的相关成员函数****************/ // 求二叉树的深度 int BTreeDepth(); // 用于求二叉树深度的递归函数,被BTreeDepth调用 int Depth(BTreeNode *&BT); // 求二叉树的宽度 int BTreeWidth(); // 求二叉树中所有结点数 int BTreeCount(); // 用于求二叉树所有结点数的递归函数,被函数BTreeCount调用 int Count(BTreeNode *&BT); // 求二叉树中所有叶子结点数 int BTreeLeafCount(); // 用于求二叉树中所有叶子结点数的递归函数,被函数BTreeLeafCount调用 int LeafCount(BTreeNode *&BT); // 输出二叉树的所有叶子结点 void BTreeLeafPrint(); // 用于输出二叉树的所有叶子结点的递归函数,被函数BTreeLeafPrint调用 void LeafPrint(BTreeNode *&BT); /***********************二叉树中从根结点到叶子结点的路径相关函数****************/ // 输出从根结点到叶子结点的路径,以及最长路径 void BTreePath(); // 输出从根结点到叶子结点的路径的递归函数,被函数BTreePath调用 void PathLeaf(BTreeNode *&BT,ElemType path[],int pathlen); // 求最长路径的递归函数,被函数BTreePaht调用 void BTreeLongpath(BTreeNode *&BT,ElemType path[],int pathlen,ElemType longpath[],int &longpathlen); // 非递归方法输出从根结点到叶子结点的路径 void BTreePath_N1(); // 返回data域为x的结点指针 void BTreeFind(ElemType x); // 返回data域为x的结点指针的递归函数,被函数BTreeFind调用 BTreeNode *FindNode(BTreeNode *&BT,ElemType x); /*************************************线索二叉树****************************/ // 线索化二叉树 void CreateThread(); // 中序线索化二叉树的递归函数,被函数CreateThread调用 void InOrderThread(BTreeNode *&BT,BTreeNode *&pre); // 中序线索化二叉树中实现中序遍历,被函数CreateThread调用 void ThInOrder(BTreeNode *&BT); /****************************销毁二叉数的相关成员函数***********************/ // 置空二叉树 void BTreeClear(); // 用于清除二叉树的递归函数,被函数BTreeClear和~BinaryTree调用 void Clear(BTreeNode *&BT); // 析构函数,清除二叉树 ~BinaryTree(); }; /******************************创建二叉数的相关成员函数*************************/ // 按照二叉树的广义表表示创建二叉树 void BinaryTree::CreateBTree1() { cout<<"输入广义表形式的二叉树:"<<endl; root=NULL; // 给树根指针置空 Create1(root); } // 递归创建二叉树,被函数CreateBTree1调用 void BinaryTree::Create1(BTreeNode *&BT) { BTreeNode *stack[MAXSIZE],*p=NULL; int k,top=-1; char ch; while((ch=getchar())!='#') { switch(ch) { case '(': top++; stack[top]=p; k=1; // 即将建立左结点 break; case ')': top--; break; case ',': k=2; // 即将建立右结点 break; default: if(!(p=new BTreeNode)) { cout<<"\n堆内存分配失败\n"; exit(1); } p->data=ch; p->left=p->right=NULL; if(BT==NULL) // p指向二叉树的根结点,建立根结点 BT=p; else // 已经建立根结点 { if(k==1) // 建立左结点 stack[top]->left=p; else // 建立右结点 stack[top]->right=p; } }//switch(ch) }//while } // 按一定次序输入二叉树中结点的值(一个字符),空格表示空树 void BinaryTree::CreateBTree2(int mark) { switch(mark) { case 1: puts("按先序输入二叉树:"); break; case 2: puts("按中序输入二叉树:"); break; case 3: puts("按后序输入二叉树:"); break; } root=NULL; // 给树根指针置空 BTreeNode *&p=root; // 定义p为指向二叉树结点的指针 Greate2(p,mark); } // 递归创建二叉树,被函数CreateBTree2调用 void BinaryTree::Greate2(BTreeNode *&BT,int mark) { char ch; ch=getchar(); switch(mark) { case 1: // 先序创建 if(ch==' ') BT=NULL; else { if(!(BT=new BTreeNode)) { cout<<"\n堆内存分配失败\n"; exit(1); } BT->data=ch; Greate2(BT->left,mark); Greate2(BT->right,mark); } break; case 2: break; case 3: break; } } // 复制二叉树 void BinaryTree::BTreeCopy(BTreeNode *&root,BTreeNode *&BT) { if(root) { if(!(BT=new BTreeNode)) { exit(1); } BT->data=root->data; BTreeCopy(root->left,BT->left); BTreeCopy(root->right,BT->right); } else BT=NULL; } /*******************************遍历二叉数的相关成员函数************************/ // 按任一种遍历次序输出二叉树中的所有结点 void BinaryTree::TraverseBTree(int mark) { srand(time(NULL)); // 产生随机种子数,用来选择相同顺序遍历的不同算法 Traverse(root,mark); cout<<endl; } // 用于遍历的递归函数,被函数TraverseBTree调用 void BinaryTree::Traverse(BTreeNode *&BT,int mark) { int option; switch(mark) { case 1: // 先序遍历 { option=rand()%3+1; switch(option) // 随机选择一种先序算法 { case 1: PreOrder(BT); break; case 2: PreOrder_N1(BT); break; case 3: PreOrder_N2(BT); break; } break; } case 2: // 中序遍历 { option = rand()%3 + 1; switch(option) // 随机选择一种中序算法 { case 1: InOrder(BT); break; case 2: InOrder_N1(BT); break; case 3: InOrder_N2(BT); break; } break; } case 3: // 后序遍历 { option=rand()%3+1; switch(option) // 随机选择一种先序算法 { case 1: PostOrder(BT); break; case 2: PostOrder_N1(BT); break; case 3: PostOrder_N2(BT); break; } break; } case 4: // 层序遍历 { LayerOrder(BT); break; } default: cout<<"mark的值无效!遍历失败!"<<endl; } } // 先序遍历的递归函数 void BinaryTree::PreOrder(BTreeNode *&BT) { if(BT!=NULL) { cout<<BT->data<<' '; PreOrder(BT->left); PreOrder(BT->right); } } // 先序遍历的非递归函数一 void BinaryTree::PreOrder_N1(BTreeNode *&BT) { BTreeNode *p; struct { BTreeNode *pt; int tag; }stack[MAXSIZE]; int top=-1; top++; stack[top].pt=BT; stack[top].tag=1; while(top>-1) // 栈不空时循环 { if(stack[top].tag==1) // 不能直接访问 { p=stack[top].pt; top--; if(p!=NULL) // 按右,左,结点顺序进栈,后进先出,即先序遍历 { top++; stack[top].pt=p->right; // 右孩子入栈 stack[top].tag=1; top++; stack[top].pt=p->left; // 左孩子入栈 stack[top].tag=1; top++; stack[top].pt=p; // 根结点入栈 stack[top].tag=0; // 可以直接访问 } } if(stack[top].tag==0) // 可以直接访问 { cout<<stack[top].pt->data<<' '; top--; } } } // 先序遍历的非递归函数二 void BinaryTree::PreOrder_N2(BTreeNode *&BT) { BTreeNode *stack[MAXSIZE],*p; int top = -1; if(BT!=NULL) { top++; // 根结点入栈 stack[top] = BT; while(top>-1) // 栈不空时循环 { p=stack[top]; top--; cout<<p->data<<" "; if(p->right != NULL) // 右孩子入栈 { top++; stack[top] = p->right; } if(p->left != NULL) // 左孩子入栈 { top++; stack[top] = p->left; } }//while }//if(root!=NULL) } // 中序遍历的递归函数 void BinaryTree::InOrder(BTreeNode *&BT) { if(BT!=NULL) { InOrder(BT->left); cout<<BT->data<<' '; InOrder(BT->right); } } // 中序遍历的非递归函数一 void BinaryTree::InOrder_N1(BTreeNode *&BT) { BTreeNode *p; struct { BTreeNode *pt; int tag; }stack[MAXSIZE]; int top = -1; top++; stack[top].pt = BT; stack[top].tag = 1; while(top>-1) // 栈不空时循环 { if(stack[top].tag == 1) // 不能直接访问 { p = stack[top].pt; top--; if(p!=NULL) // 按右,左,结点顺序进栈,后进先出,即先序遍历 { top++; stack[top].pt=p->right; // 右孩子入栈 stack[top].tag = 1; top++; stack[top].pt = p; // 根结点入栈 stack[top].tag = 0; // 可以直接访问 top++; stack[top].pt =p->left; // 左孩子入栈 stack[top].tag = 1; } } if(stack[top].tag == 0) // 可以直接访问 { cout<<stack[top].pt->data<<' '; top--; } } } // 中序遍历的非递归函数二 void BinaryTree::InOrder_N2(BTreeNode *&BT) { BTreeNode *stack[MAXSIZE],*p; int top = -1; if(BT != NULL) { p = BT; while(top > -1||p != NULL) { while(p != NULL) // 所有左结点入栈 { top++; stack[top] = p; p = p->left; } if(top > -1) { p = stack[top]; top--; cout<<p->data<<" "; p = p->right; } } }//if } // 后序遍历的递归函数 void BinaryTree::PostOrder(BTreeNode *&BT) { if(BT!=NULL) { PostOrder(BT->left); PostOrder(BT->right); cout<<BT->data<<' '; } } // 后序遍历的非递归函数一 void BinaryTree::PostOrder_N1(BTreeNode *&BT) { BTreeNode *p; struct { BTreeNode *pt; int tag; }stack[MAXSIZE]; int top = -1; top++; stack[top].pt = BT; stack[top].tag = 1; while(top>-1) // 栈不空时循环 { if(stack[top].tag == 1) // 不能直接访问 { p = stack[top].pt; top--; if(p!=NULL) // 按右,左,结点顺序进栈,后进先出,即先序遍历 { top++; stack[top].pt = p; // 根结点入栈 stack[top].tag = 0; // 可以直接访问 top++; stack[top].pt=p->right; // 右孩子入栈 stack[top].tag = 1; top++; stack[top].pt =p->left; // 左孩子入栈 stack[top].tag = 1; } } if(stack[top].tag == 0) // 可以直接访问 { cout<<stack[top].pt->data<<' '; top--; } } } // 后序遍历的非递归函数二 void BinaryTree::PostOrder_N2(BTreeNode *&BT) { BTreeNode *stack[MAXSIZE],*p,*q; q=BT; int top = -1,flag; if(q != NULL) { do { while(q != NULL) // 所有左结点入栈 { top++; stack[top] = q; q = q->left; } p=NULL; // p指向当前结点的前一个已访问的结点 flag=1; // 设置q的访问标记为已访问过 while(top > -1&&flag) { q = stack[top]; // 取出当前栈顶元素 if(q->right == p) // 当右孩子不存在或已被访问时,则访问 { cout<<q->data<<" "; top--; p = q; // p指向刚被访问的结点 } else { q = q->right; // 指向右孩子 flag = 0; // 设置未被访问的标记 } } }while(top>-1); }//if } // 层序遍历的非递归函数 void BinaryTree::LayerOrder(BTreeNode *&BT) { BTreeNode *Queue[MAXSIZE]; // 定义存储二叉树结点指针的数组空间作为队列使用 int front=0,rear=0; // 定义队首指针和队尾指针,初始均置0表示空队 BTreeNode *p; if(BT!=NULL) { rear=(rear+1)%MAXSIZE; // 后移队尾指针 Queue[rear]=BT; // 将树根结点指针进队 } while(front!=rear) // 当队列非空时执行循环 { front=(front+1)%MAXSIZE; // 后移队首指针 p=Queue[front]; // 删除队首结点的值 cout<<p->data<<' '; // 输出队首结点的值 if(p->left!=NULL) // 若结点存在左孩子,则左孩子结点指针进队 { rear=(rear+1)%MAXSIZE; Queue[rear]=p->left; } if(p->right!=NULL) // 若结点存在右孩子,则右孩子结点指针进队 { rear=(rear+1)%MAXSIZE; Queue[rear]=p->right; } } } // 按照二叉树的广义表表示输出整个二叉树 void BinaryTree::GPrintBTree() { GPrint(root); cout<<endl; } // 广义表形式输出整个二叉树的递归函数,被函数Print调用 void BinaryTree::GPrint(BTreeNode *&BT) { if(BT==NULL) return; // 树为空时返回 else // 否则执行如下操作 { cout<<BT->data; // 输出根结点的值 if(BT->left!=NULL||BT->right!=NULL) { cout<<'('; // 输出左括号 GPrint(BT->left); // 输出左子树 if(BT->right!=NULL) cout<<','; // 若右子树不为空则输出逗号分隔符 GPrint(BT->right); // 输出右子树 cout<<')'; // 输出右括号 } } } // 以凹凸表示法输出二叉树 void BinaryTree::OPrintTree() { cout<<endl; BTreeNode *stack[MAXSIZE],*p; int level[MAXSIZE][2],top=-1,n,i,width=4; int maxwidth=40; char type[20]; char *pre_type=type; if(root!=NULL) { top++; // 根结点入栈 stack[top]=root; level[top][0]=width; level[top][1]=2; // 2表示是根 while(top>-1) { p=stack[top]; // 退栈并凹入显示该结点值 n=level[top][0]; switch(level[top][1]) { case 0: pre_type="左结点"; break; case 1: pre_type="右结点"; break; case 2: pre_type="根结点"; } for(i=1;i<=n;i++) // n为显示场宽,字符以右对齐显示 cout<<" "; cout<<" "<<p->data<<"("<<pre_type<<")"; for(i=n+1;i<=maxwidth;i+=2) cout<<"--"; cout<<endl; top--; if(p->right!=NULL) { top++; // 将右子树树根结点入栈 stack[top]=p->right; level[top][0]=n+width; // 显示场宽增加width level[top][1]=1; // 1表示右子树 } if(p->left!=NULL) { top++; // 将左子树树根结点入栈 stack[top]=p->left; level[top][0]=n+width; // 显示场宽增加width level[top][1]=0; // 0表示左子树 } }//while }//if } /******************计算二叉数深度,宽度,叶子,结点的相关成员函数******************/ // 求二叉树的深度 int BinaryTree::BTreeDepth() { return Depth(root); } // 用于求二叉树深度的递归函数,被BTreeDepth调用 int BinaryTree::Depth(BTreeNode *&BT) { if(BT==NULL) return 0; // 对于空树,返回0并结束递归 else { int dep_left=Depth(BT->left); // 计算左子树的深度 int dep_right=Depth(BT->right); // 计算右子树的深度 if(dep_left>dep_right) // 返回树的深度 return dep_left+1; else return dep_right+1; }
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服