信息安全数据结构实验1.docx
- 文档编号:24408191
- 上传时间:2023-05-27
- 格式:DOCX
- 页数:18
- 大小:43.13KB
信息安全数据结构实验1.docx
《信息安全数据结构实验1.docx》由会员分享,可在线阅读,更多相关《信息安全数据结构实验1.docx(18页珍藏版)》请在冰豆网上搜索。
信息安全数据结构实验1
实验二栈的应用-括号匹配
一、实验目的
1、掌握STL中栈的基本使用
2、练习使用栈进行程序编写
二、实验内容
题目一:
STL
下面代码使用STL中的栈进行序列的反转,请修改好下面代码中的语法错误,编译运行
#include
intmain()
/*Pre:
Theusersuppliesanintegernandndecimalnumbers.
Post:
Thenumbersareprintedinreverseorder.
Uses:
TheSTLclassstackanditsmethods*/
{
intn;
doubleitem;
stack
cout<<"Typeinanintegernfollowedbyndecimalnumbers."
< <<"Thenumberswillbeprintedinreverseorder." < cin>>n; for(inti=0;i cin>>item; numbers.push(item); } cout< while(! numbers.empty()){ cout< numbers.pop(); } cout< } 提示: (1)由于程序是用了STL(标准模板库,可以简单的看成是一个函数库,在其中有各种有用的类、函数和算法),栈在其中有实现。 栈在STL中的实现用到了类模板,也就是说其栈是独立于类型的,模板提供参数化类型,也就是能将类型名作为参数传递给接收方来建立类或函数。 比如stack (2)要使用c++的输入输出需要加上几行语句如下,因为cout和cin是在命名空间std中的: #include usingnamespacestd; 题目二: 括号匹配 使用STL中的栈编写程序,实现算术表达式中的括号匹配(有能力的同学可以同时进行小括号,大括号,中括号的匹配) 注意: (1)配对的算术表达式中左右括号的数目应相等 例如: 表达式(a+b))和a+b)中的括号不配对 (2)对的算术表达式中每一个左括号都一定有一个右括号与之匹配,并且一定是先出现左括号,才能有右括号 例如: 表达式)a+b(+c和(b+a))+(c+d也属于不配对的情况 算法提示: 方式是先创建一个存放左括号的空栈,并将“#”作为栈底元素。 顺序扫描表达式,当遇到非括号时,继续扫描,遇到“(”时,进栈,而遇到“)”时,与栈顶元素比较,如果括号匹配,栈顶元素退栈,继续扫描表达式,否则,报错退出。 括号配对检查的原则是: 对表达式从左向右扫描。 当遇到左括号时,左括号入栈;而遇到右括号时,首先将栈中的栈顶元素弹出栈,再比较弹出元素是否与右括号匹配,如果两者匹配,则操作继续;否则,检查出错,打印“no”,并停止操作。 当表达式全部扫描完后,如果栈顶元素为“#”,说明括号作用层次嵌套正确,打印“yes”,并停止操作。 附录: STL中栈的使用 #pragmawarning(disable: 4786) #include #include usingnamespacestd; typedefstack intmain() { STACK_INTstack1; cout<<"stack1.empty()returned"<< (stack1.empty()? "true": "false")< cout<<"stack1.push (2)"< stack1.push (2); if(! stack1.empty())//Function3 cout<<"stack1.top()returned"<< stack1.top()< cout<<"stack1.push(5)"< stack1.push(5); if(! stack1.empty())//Function3 cout<<"stack1.top()returned"<< stack1.top()< cout<<"stack1.push(11)"< stack1.push(11); if(! stack1.empty())//Function3 cout<<"stack1.top()returned"<< stack1.top()< //Modifythetopitem.Setitto6. if(! stack1.empty()){//Function3 cout<<"stack1.top()=6;"< stack1.top()=6;//Function1 } //Repeatuntilstackisempty while(! stack1.empty()){//Function3 constint&t=stack1.top();//Function2 cout<<"stack1.top()returned"< cout<<"stack1.pop()"< stack1.pop(); } } 运行结果: stack1.empty()returnedtrue stack1.push (2) stack1.top()returned2 stack1.push(5) stack1.top()returned5 stack1.push(11) stack1.top()returned11 stack1.top()=6; stack1.top()returned6 stack1.pop() stack1.top()returned5 stack1.pop() stack1.top()returned2 stack1.pop() 实验三按层次构造二叉树及二叉树遍历 一、实验目的 1、设计数据结构和算法,实现按层次构造二叉树的算法 2、掌握树的前根序、中根序和后根序遍历算法 二、实验内容 1、实验题目 按层次(从上到下,从左到右的顺序)输入树的结点,如果该结点为空,则用一个特定的值替代(比如0或者.)。 例如下面的图中,输入为ebfad.g..c(当然为了方便输入,也可以用#结束字符串的输入) 要求构造一棵如下的二叉树,当二叉树构造成功后,需要对其进行先序遍历,后序遍历,中序遍历。 2、按层次构造树的两种方法 对于如下的一棵树 输入: 为了构造上图所示的这样一棵二叉树,键盘上输入的顺序如下: ebfad.g..c# 其中可以看到这是根据层次的一种输入,先输入第一层的结点,然后是第二层的结点,第三层….直到把所有的带信息的结点输入完。 也可以看到,在输入的序列中,有.号,这是代表结点为空。 注意在输入的时候,为空的结点也要这样输入进去。 构造二叉树: 方法一: 用队列 queue queue 假如我们把读入的数据放到一个队列中A,用于方便我们的后续处理,那么,在读入后,这个队列中的数据为ebfad.g..c,其中e为队列头存放的元素值(即该指针所指向的节点空间数据域中的值为e),而点代表空指针NULL 把数据读入队列A中的方法如下: Binary_node*tempNode=newBinary_node(); cin>>tempNode->data; tempNode->left=NULL; tempNode->right=NULL; A.push(tempNode); 为了按层次的构造二叉树,我们还要使用一个队列B,这个队列中保存的是指向要有儿子结点的父亲结点的指针。 下面是这两个队列的变化和树的构造变化情况: (1)第一步很特殊,首先是树根 Binary_node*pNode=A.front(); A.pop(); B.push(pNode); A: bfad.g..c B: e 树: (2)后面的每一步都是从A中取出两个队首,放入B队列尾部(如果为NULL则不放)。 从B中取出队首,队列A中取出的元素正好是B中取出元素的小孩子 Binary_node*pfather=B.front(); B.pop(); Binary_node*pLchild=A.front();//先出来的是左孩子 A.pop(); Binary_node*pRchild=A.front(); A.pop(); pfather->left=pLchild; pfather->right=pRchild; //先放入左孩子 if(pLchild! =NULL) { B.push(pLchild); } if(pRchild! =NULL) { B.push(pLchild); } A: ad.g..c B: bf 树: (3) A: .g..c B: fad 树: (4) A: ..c B: adg 树: (5) A: c B: dg 树: (6) A: 空(当队列A为空的时候整个算法结束,树构造成功) B: g 树: 第二种方法: 给树的结点按层次从上到下,从左到右编号(编号从1开始,空节点也要编号),利用父亲跟小孩的编号的关系来编写代码。 即节点的编号除以2,得到的商代表这该节点父亲节点的编号,得到的余数为0,则表示该节点为父亲的左孩子,若得到的余数为1,则表示该节点为父亲的右孩子。 实现方法可以为, (1)为每个节点分配空间; (2)定义一个一维数组,该数组中存放的元素为指向节点的指针,将每个分配好空间的节点的指针放入该一维数组中(3)逐一访问节点,确定节点的父子关系。 当除了根节点外,每个节点的父亲都确定后,这颗二叉树就构造好了。 两种方法分析: 用队列的方法,实现有点难度,但是灵活。 数组的方法,实现比较简单,但是有局限性。 3、程序简单模板 下面给#include usingnamespacestd; structBinary_node { chardata;//datamembers Binary_node*left; Binary_node*right; }; classBinary_tree { public: Binary_tree();//构造函数,里面将root=NULL; //通过队列中保存的数据,构造树 voidbuildTree(void); //遍历二叉树 voidpreorder(void); voidinorder(void); voidpostorder(void); private: //遍历树的辅助函数 voidrecursive_inorder(Binary_node*root); voidrecursive_preorder(Binary_node*root); voidrecursive_postorder(Binary_node*root); Binary_node*root;//树根 }; 出一个C++的类,供参考,自己写代码的时候并不要求一定如此。 附录: STL中队列的使用 注: 队列,这里也不要求大家再去自己实现一个有关队列的类,直接用标准模板库(STL)中的队列就可以了。 需要#include STL中的queue,里面的一些成员函数如下(这里仅仅描述也许会用到的几个,具体不明白可以查找msdn,搜索queueclass): front: Returnsareferencetothefirstelementatthefrontofthequeue. pop: Removesanelementfromthefrontofthequeue push: Addsanelementtothebackofthequeue empty: Testsifthequeueisempty 程序示例: //queue: : push(),queue: : pop(),queue: : empty(),queue: : back(), //queue: : front(),queue: : size() #include #include usingnamespacestd; typedefqueue typedefqueue intmain(void) { intsize_q; INTQUEUEq; CHARQUEUEp; //Insertitemsinthequeue q.push(42); q.push(100); q.push(49); q.push(201); //Outputthesizeofqueue size_q=q.size(); cout<<"sizeofqis: "< //Outputitemsinqueueusingfront() //andusepop()togettonextitemuntil //queueisempty while(! q.empty()) { cout< q.pop(); } //Insertitemsinthequeue p.push("cat"); p.push("ape"); p.push("dog"); p.push("mouse"); p.push("horse"); //Outputtheiteminsertedlastusingback() cout< //Outputthesizeofqueue size_q=p.size(); cout<<"sizeofpis: "< //Outputitemsinqueueusingfront() //andusepop()togettonextitemuntil //queueisempty while(! p.empty()) { cout< p.pop(); } } 输出结果: sizeofqis: 4 42 100 49 201 horse sizeofpis: 5 cat ape dog mouse horse 实验四二叉排序树 一、实验目的 掌握二叉排序树的构造 二、实验内容 (1)构建一个二叉排序树(中序遍历的时候会输出排序结果),树中结点数据取自数组a[10]。 a[10]={8,3,6,1,5,2,9,7,4,0} (2)分别用三种遍历方法输出遍历结果。 (3)键盘输入一个值x,要求在生成好的二叉排序树中查找这个值x,如果找到,则输出“找到了”,没有找到,则输出“没有找到” 实验五排序 一、实验目的 掌握快速排序 二、实验要求 复习排序方法,掌握快速排序算法,并自己编写代码实现 三、实验内容 1、快速排序 编写程序,实现快速排序。 从键盘上输入10个整数,存放在数组中,然后用快速排序法对其从小到大进行排序,并输出排序结果。 2、选作 编写程序,实现堆排序。 实验六最短路径 一、实验目的 1.学习掌握图的存储结构 2.学会编写求最短路径的算法 二、实验内容 1、实验题目 编写代码实现Dijkstra生成最短路径的算法,其中要有完整的图的输入输出 2、简单介绍 图的存储: 用邻接矩阵,这样会方便不少。 邻接矩阵是一个二维数组,数组中的元素是边的权(一些数值),数组下标号为结点的标号。 (1)例如二维数组中的一个元素M[5][6]的值为39,则表示结点5、6连接,且其上的权值为39。 (2)用邻接矩阵存储图,对图的读写就简单了。 因为邻接矩阵就是一个二维数组,因此对图的读写就是对二维数组的操作。 只要能弄清楚边的编号,就能把图读入了。 用一对结点表示边(也就是输入的时候输入一对结点的编号) 求最短路径的算法: 求最短路径就是求图中的每一个点到图中某一个给定点(这里认为是编号为0的点)的最短距离。 具体算法就是初始有一个旧图,一个新图。 开始的时候旧图中有所有的结点,新图中初始为只有一个结点(源点,路径的源头)。 整个算法就是不停的从旧图中往新图中添加点,直到所有的点都添加到新图中为止。 要实现这个算法,除了用二维数组保存图,还需要使用到两个辅助的数组 数组find[N]: 此数组是用来表示标号对应的结点是否已经被添加到新图中(因为只有旧图中的点我们才需要添加到新图中,并且只有旧图中点到源点的距离,我们才需要进行更新)其中N为图中结点的个数。 数组distance[N]: 此数组记录图中的点到源点的距离。 这个数组里面存放的值是不断进行更新的。 其中N为图中结点的个数。 3、程序简单模板 只是参考,不需要照着这个来写 //最短路径 #ifndefMYGRAPH_H_ #defineMYGRAPH_H_ classMyGraph { public: voidreadUndirectedGraph(); MyGraph(intsize);//构造函数中设置图的大小,分配空间 voidwriteGraph(); voidshortPath(intsource);//求最短路径 protected: private: int**m_graph;//用二维数组保存图 intm_size;//图的大小 }; #endif ///////////////////////////////////////////////////////////////////// //构造函数中设置图的大小,分配空间 MyGraph: : MyGraph(intsize) { inti,j; m_size=size; //给图分配空间 m_graph=newint*[m_size]; for(i=0;i { m_graph[i]=newint[m_size]; } for(i=0;i { for(j=0;j { m_graph[i][j]=INT_MAX; } } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 信息 安全 数据结构 实验
![提示](https://static.bdocx.com/images/bang_tan.gif)