数据结构-基本算法演示程序(附源码)

合集下载

数据结构平衡二叉树的操作演示

数据结构平衡二叉树的操作演示

平衡二叉树操作的演示1.需求分析本程序是利用平衡二叉树,实现动态查找表的基本功能:创建表,查找、插入、删除。

具体功能:(1)初始,平衡二叉树为空树,操作界面给出创建、查找、插入、删除、合并、分裂六种操作供选择。

每种操作均提示输入关键字。

每次插入或删除一个结点后,更新平衡二叉树的显示。

(2)平衡二叉树的显示采用凹入表现形式。

(3)合并两棵平衡二叉树。

(4)把一棵二叉树分裂为两棵平衡二叉树,使得在一棵树中的所有关键字都小于或等于x,另一棵树中的任一关键字都大于x。

如下图:2.概要设计平衡二叉树是在构造二叉排序树的过程中,每当插入一个新结点时,首先检查是否因插入新结点而破坏了二叉排序树的平衡性,若是则找出其中的最小不平衡子树,在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。

具体步骤:(1)每当插入一个新结点,从该结点开始向上计算各结点的平衡因子,即计算该结点的祖先结点的平衡因子,若该结点的祖先结点的平衡因子的绝对值不超过1,则平衡二叉树没有失去平衡,继续插入结点;(2)若插入结点的某祖先结点的平衡因子的绝对值大于1,则找出其中最小不平衡子树的根结点;(3)判断新插入的结点与最小不平衡子树的根结点个关系,确定是那种类型的调整;(4)如果是LL型或RR型,只需应用扁担原理旋转一次,在旋转过程中,如果出现冲突,应用旋转优先原则调整冲突;如果是LR型或RL型,则需应用扁担原理旋转两次,第一次最小不平衡子树的根结点先不动,调整插入结点所在子树,第二次再调整最小不平衡子树,在旋转过程中,如果出现冲突,应用旋转优先原则调整冲突;(5)计算调整后的平衡二叉树中各结点的平衡因子,检验是否因为旋转而破坏其他结点的平衡因子,以及调整后平衡二叉树中是否存在平衡因子大于1的结点。

流程图3.详细设计二叉树类型定义:typedef int Status;typedef int ElemType;typedef struct BSTNode{ElemType data;int bf;struct BSTNode *lchild ,*rchild;} BSTNode,* BSTree;Status SearchBST(BSTree T,ElemType e)//查找void R_Rotate(BSTree &p)//右旋void L_Rotate(BSTree &p)//左旋void LeftBalance(BSTree &T)//插入平衡调整void RightBalance(BSTree &T)//插入平衡调整Status InsertAVL(BSTree &T,ElemType e,int &taller)//插入void DELeftBalance(BSTree &T)//删除平衡调整void DERightBalance(BSTree &T)//删除平衡调整Status Delete(BSTree &T,int &shorter)//删除操作Status DeleteAVL(BSTree &T,ElemType e,int &shorter)//删除操作void merge(BSTree &T1,BSTree &T2)//合并操作void splitBSTree(BSTree T,ElemType e,BSTree &T1,BSTree &T2)//分裂操作void PrintBSTree(BSTree &T,int lev)//凹入表显示附录源代码:#include<stdio.h>#include<stdlib.h>//#define TRUE 1//#define FALSE 0//#define OK 1//#define ERROR 0#define LH +1#define EH 0#define RH -1//二叉类型树的类型定义typedef int Status;typedef int ElemType;typedef struct BSTNode{ElemType data;int bf;//结点的平衡因子struct BSTNode *lchild ,*rchild;//左、右孩子指针} BSTNode,* BSTree;/*查找算法*/Status SearchBST(BSTree T,ElemType e){if(!T){return 0; //查找失败}else if(e == T->data ){return 1; //查找成功}else if (e < T->data){return SearchBST(T->lchild,e);}else{return SearchBST(T->rchild,e);}}//右旋void R_Rotate(BSTree &p){BSTree lc; //处理之前的左子树根结点lc = p->lchild; //lc指向的*p的左子树根结点p->lchild = lc->rchild; //lc的右子树挂接为*P的左子树lc->rchild = p;p = lc; //p指向新的根结点}//左旋void L_Rotate(BSTree &p){BSTree rc;rc = p->rchild; //rc指向的*p的右子树根结点p->rchild = rc->lchild; //rc的左子树挂接为*p的右子树rc->lchild = p;p = rc; //p指向新的根结点}//对以指针T所指结点为根结点的二叉树作左平衡旋转处理,//本算法结束时指针T指向新的根结点void LeftBalance(BSTree &T){BSTree lc,rd;lc=T->lchild;//lc指向*T的左子树根结点switch(lc->bf){ //检查*T的左子树的平衡度,并做相应的平衡处理case LH: //新结点插入在*T的左孩子的左子树,要做单右旋处理T->bf = lc->bf=EH;R_Rotate(T);break;case RH: //新结点插入在*T的左孩子的右子树上,做双旋处理rd=lc->rchild; //rd指向*T的左孩子的右子树根switch(rd->bf){ //修改*T及其左孩子的平衡因子case LH: T->bf=RH; lc->bf=EH;break;case EH: T->bf=lc->bf=EH;break;case RH: T->bf=EH; lc->bf=LH;break;}rd->bf=EH;L_Rotate(T->lchild); //对*T的左子树作左旋平衡处理R_Rotate(T); //对*T作右旋平衡处理}}//右平衡旋转处理void RightBalance(BSTree &T){BSTree rc,ld;rc=T->rchild;switch(rc->bf){case RH:T->bf= rc->bf=EH;L_Rotate(T);break;case LH:ld=rc->lchild;switch(ld->bf){case LH: T->bf=RH; rc->bf=EH;break;case EH: T->bf=rc->bf=EH;break;case RH: T->bf = EH; rc->bf=LH;break;}ld->bf=EH;R_Rotate(T->rchild);L_Rotate(T);}}//插入结点Status InsertAVL(BSTree &T,ElemType e,int &taller){//taller反应T长高与否if(!T){//插入新结点,树长高,置taller为trueT= (BSTree) malloc (sizeof(BSTNode));T->data = e;T->lchild = T->rchild = NULL;T->bf = EH;taller = 1;}else{if(e == T->data){taller = 0;return 0;}if(e < T->data){if(!InsertAVL(T->lchild,e,taller))//未插入return 0;if(taller)//已插入到*T的左子树中且左子树长高switch(T->bf){//检查*T的平衡度,作相应的平衡处理case LH:LeftBalance(T);taller = 0;break;case EH:T->bf = LH;taller = 1;break;case RH:T->bf = EH;taller = 0;break;}}else{if (!InsertAVL(T->rchild,e,taller)){return 0;}if(taller)//插入到*T的右子树且右子树增高switch(T->bf){//检查*T的平衡度case LH:T->bf = EH;taller = 0;break;case EH:T->bf = RH;taller = 1;break;case RH:RightBalance(T);taller = 0;break;}}}return 1;}void DELeftBalance(BSTree &T){//删除平衡调整BSTree lc,rd;lc=T->lchild;switch(lc->bf){case LH:T->bf = EH;//lc->bf= EH;R_Rotate(T);break;case EH:T->bf = EH;lc->bf= EH;R_Rotate(T);break;case RH:rd=lc->rchild;switch(rd->bf){case LH: T->bf=RH; lc->bf=EH;break;case EH: T->bf=lc->bf=EH;break;case RH: T->bf=EH; lc->bf=LH;break;}rd->bf=EH;L_Rotate(T->lchild);R_Rotate(T);}}void DERightBalance(BSTree &T) //删除平衡调整{BSTree rc,ld;rc=T->rchild;switch(rc->bf){case RH:T->bf= EH;//rc->bf= EH;L_Rotate(T);break;case EH:T->bf= EH;//rc->bf= EH;L_Rotate(T);break;case LH:ld=rc->lchild;switch(ld->bf){case LH: T->bf=RH; rc->bf=EH;break;case EH: T->bf=rc->bf=EH;break;case RH: T->bf = EH; rc->bf=LH;break;}ld->bf=EH;R_Rotate(T->rchild);L_Rotate(T);}}void SDelete(BSTree &T,BSTree &q,BSTree &s,int &shorter){if(s->rchild){SDelete(T,s,s->rchild,shorter);if(shorter)switch(s->bf){case EH:s->bf = LH;shorter = 0;break;case RH:s->bf = EH;shorter = 1;break;case LH:DELeftBalance(s);shorter = 0;break;}return;}T->data = s->data;if(q != T)q->rchild = s->lchild;elseq->lchild = s->lchild;shorter = 1;}//删除结点Status Delete(BSTree &T,int &shorter){ BSTree q;if(!T->rchild){q = T;T = T->lchild;free(q);shorter = 1;}else if(!T->lchild){q = T;T= T->rchild;free(q);shorter = 1;}else{SDelete(T,T,T->lchild,shorter);if(shorter)switch(T->bf){case EH:T->bf = RH;shorter = 0;break;case LH:T->bf = EH;shorter = 1;break;case RH:DERightBalance(T);shorter = 0;break;}}return 1;}Status DeleteAVL(BSTree &T,ElemType e,int &shorter){ int sign = 0;if (!T){return sign;}else{if(e == T->data){sign = Delete(T,shorter);return sign;}else if(e < T->data){sign = DeleteAVL(T->lchild,e,shorter);if(shorter)switch(T->bf){case EH:T->bf = RH;shorter = 0;break;case LH:T->bf = EH;shorter = 1;break;case RH:DERightBalance(T);shorter = 0;break;}return sign;}else{sign = DeleteAVL(T->rchild,e,shorter);if(shorter)switch(T->bf){case EH:T->bf = LH;shorter = 0;break;case RH:T->bf = EH;break;case LH:DELeftBalance(T);shorter = 0;break;}return sign;}}}//合并void merge(BSTree &T1,BSTree &T2){int taller = 0;if(!T2)return;merge(T1,T2->lchild);InsertAVL(T1,T2->data,taller);merge(T1,T2->rchild);}//分裂void split(BSTree T,ElemType e,BSTree &T1,BSTree &T2){ int taller = 0;if(!T)return;split(T->lchild,e,T1,T2);if(T->data > e)InsertAVL(T2,T->data,taller);elseInsertAVL(T1,T->data,taller);split(T->rchild,e,T1,T2);}//分裂void splitBSTree(BSTree T,ElemType e,BSTree &T1,BSTree &T2){ BSTree t1 = NULL,t2 = NULL;split(T,e,t1,t2);T1 = t1;T2 = t2;return;}//构建void CreatBSTree(BSTree &T){int num,i,e,taller = 0;printf("输入结点个数:");scanf("%d",&num);printf("请顺序输入结点值\n");for(i = 0 ;i < num;i++){printf("第%d个结点的值",i+1);scanf("%d",&e);InsertAVL(T,e,taller) ;}printf("构建成功,输入任意字符返回\n");getchar();getchar();}//凹入表形式显示方法void PrintBSTree(BSTree &T,int lev){int i;if(T->rchild)PrintBSTree(T->rchild,lev+1);for(i = 0;i < lev;i++)printf(" ");printf("%d\n",T->data);if(T->lchild)PrintBSTree(T->lchild,lev+1);void Start(BSTree &T1,BSTree &T2){int cho,taller,e,k;taller = 0;k = 0;while(1){system("cls");printf(" 平衡二叉树操作的演示 \n\n");printf("********************************\n");printf(" 平衡二叉树显示区 \n");printf("T1树\n");if(!T1 )printf("\n 当前为空树\n");else{PrintBSTree(T1,1);}printf("T2树\n");if(!T2 )printf("\n 当前为空树\n");elsePrintBSTree(T2,1);printf("\n********************************************************************* *********\n");printf("T1操作:1.创建 2.插入 3.查找 4.删除 10.分裂\n");printf("T2操作:5.创建 6.插入 7.查找 8.删除 11.分裂\n");printf(" 9.合并 T1,T2 0.退出\n");printf("*********************************************************************** *******\n");printf("输入你要进行的操作:");scanf("%d",&cho);switch(cho){case 1:CreatBSTree(T1);break;case 2:printf("请输入要插入关键字的值");scanf("%d",&e);InsertAVL(T1,e,taller) ;break;case 3:printf("请输入要查找关键字的值");scanf("%d",&e);if(SearchBST(T1,e))printf("查找成功!\n");elseprintf("查找失败!\n");printf("按任意键返回87"); getchar();getchar();break;case 4:printf("请输入要删除关键字的值"); scanf("%d",&e);if(DeleteAVL(T1,e,k))printf("删除成功!\n");elseprintf("删除失败!\n");printf("按任意键返回");getchar();getchar();break;case 5:CreatBSTree(T2);break;case 6:printf("请输入要插入关键字的值"); scanf("%d",&e);InsertAVL(T2,e,taller) ;break;case 7:printf("请输入要查找关键字的值"); scanf("%d",&e);if(SearchBST(T2,e))printf("查找成功!\n");elseprintf("查找失败!\n");printf("按任意键返回");getchar();getchar();break;case 8:printf("请输入要删除关键字的值"); scanf("%d",&e);if(DeleteAVL(T2,e,k))printf("删除成功!\n");elseprintf("删除失败!\n");printf("按任意键返回");getchar();getchar();break;case 9:merge(T1,T2);T2 = NULL;printf("合并成功,按任意键返回"); getchar();getchar();break;case 10:printf("请输入要中间值字的值"); scanf("%d",&e);splitBSTree(T1,e,T1,T2) ;printf("分裂成功,按任意键返回"); getchar();getchar();break;case 11:printf("请输入要中间值字的值"); scanf("%d",&e);splitBSTree(T2,e,T1,T2) ;printf("分裂成功,按任意键返回"); getchar();getchar();break;case 0:system("cls");exit(0);}}}main(){BSTree T1 = NULL;BSTree T2 = NULL;Start(T1,T2);}。

c语言数据结构与算法pdf

c语言数据结构与算法pdf

c语言数据结构与算法C语言是计算机编程的一种语言,广泛用于数据结构与算法的实现和分析。

数据结构是组织和存储数据的方式,而算法是一系列解决问题的步骤。

在C语言中,常见的数据结构包括数组、链表、栈、队列、树、图等,算法则包括排序、搜索、动态规划、贪心算法等。

以下是C语言中一些基本数据结构和算法的简要介绍:1. 数组:数组是连续存储的一组元素,可以通过索引来访问。

数组的大小在编译时确定,因此动态扩展能力有限。

2. 链表:链表是由一系列节点组成的数据结构,每个节点包含数据部分和指向下一个节点的指针。

链表的大小在运行时可以动态变化。

3. 栈:栈是一种后进先出(LIFO)的数据结构,主要操作包括压栈(push)和出栈(pop)。

栈通常用于解决递归、括号匹配等问题。

4. 队列:队列是一种先进先出(FIFO)的数据结构,主要操作包括入队(enqueue)和出队(dequeue)。

队列常用于任务调度、缓冲处理等问题。

5. 树:树是由节点组成的数据结构,每个节点包含数据部分和指向子节点的指针。

树的结构可以是二叉树、平衡树(如AVL树)、红黑树等。

树常用于表示层次关系、索引等。

6. 图:图是由节点和边组成的数据结构。

节点表示实体,边表示节点之间的关系。

图的表示方法有邻接矩阵和邻接表等。

图的应用包括最短路径、拓扑排序等。

在C语言中实现数据结构和算法,可以提高编程能力,更好地理解和解决复杂问题。

常见的算法包括冒泡排序、选择排序、插入排序、快速排序等排序算法,以及二分搜索、深度优先搜索、广度优先搜索等搜索算法。

此外,动态规划、贪心算法等高级算法也在C语言中得到广泛应用。

学习和掌握C语言的数据结构和算法,有助于提高编程水平,为解决实际问题奠定基础。

数据结构上机实验源代码

数据结构上机实验源代码

数据结构上机实验源代码栈的应用十进制数转换为八进制数,逆序输出所输入的数实验代码://stack.h,头文件class stack{public:stack();bool empty()const;bool full()const;error_code gettop(elementtype &x)const;error_code push(const elementtype x);error_code pop();private:int count;elementtype data[maxlen];};stack::stack(){count=0;}bool stack::empty()const{return count==0;}bool stack::full()const{return count==maxlen;}error_code stack::gettop(elementtype &x)const{if(empty())return underflow;else{x=data[count-1];return success;}}error_code stack::push(const elementtype x){if(full())return overflow;data[count]=x;count++;return success;}error_code stack::pop(){if(empty())return underflow;count--;return success;}//主程序#include<iostream.h>enum error_code{overflow,underflow,success};typedef int elementtype;const int maxlen=20;#include"stack.h"void read_write() //逆序输出所输入的数{stack s;int i;int n,x;cout<<"please input num int n:";cin>>n;for(i=1;i<=n;i++){cout<<"please input a num:";cin>>x;s.push(x);}while(!s.empty()){s.gettop(x);cout<<x<<" ";s.pop();}cout<<endl;}void Dec_to_Ocx(int n) //十进制转换为八进制{stack s1;int mod,x;while(n!=0){mod=n%8;s1.push(mod);n=n/8;}cout<<"the ocx of the dec is:";while(!s1.empty()){s1.gettop(x);cout<<x;s1.pop();}cout<<endl;}void main(){int n;// read_write();cout<<"please input a dec:";cin>>n;Dec_to_Ocx(n);}队列的应用打印n行杨辉三角实验代码://queue.hclass queue{public:queue(){count=0;front=rear=0;}bool empty(){return count==0;}bool full(){return count==maxlen-1;}error_code get_front(elementtype &x){if(empty())return underflow;x=data[(front+1)%maxlen];return success;}error_code append(const elementtype x){if(full())return overflow;rear=(rear+1)%maxlen;data[rear]=x;count++;return success;}error_code serve(){if(empty())return underflow;front=(front+1)%maxlen;count--;return success;}private:int count;int front;int rear;int data[maxlen];};//主程序#include<iostream.h>enum error_code{overflow,underflow,success};typedef int elementtype;const int maxlen=20;#include"queue.h"void out_number(int n) //打印前n行的杨辉三角{int s1,s2;int i;int j;int k;queue q;for(i=1;i<=(n-1)*2;i++)cout<<" ";cout<<"1 "<<endl;q.append(1);for(i=2;i<=n;i++){s1=0;for(k=1;k<=(n-i)*2;k++)cout<<" ";for(j=1;j<=i-1;j++){q.get_front(s2);q.serve();cout<<s1+s2<<" ";q.append(s1+s2);s1=s2;}cout<<"1 "<<endl;q.append(1);}}void main(){int n;cout<<"please input n:";cin>>n;out_number(n);}单链表实验实验目的:实验目的(1)理解线性表的链式存储结构。

数据结构-算术表达式求值(含需求分析和源代码)

数据结构-算术表达式求值(含需求分析和源代码)

需求分析(附代码)一、需求分析(1)首先定义两个栈OPTR、OPND,栈OPTR用于存放运算符,栈OPND 用于存放操作数;定义一个一维数组expr【】存放表达式串。

(2)主函数主要包括两部分:(1)判断运算符优先权,返回优先权高的;(2)操作函数。

(3)开始将‘#’入操作符栈,通过一个函数来判别算术运算符的优先级。

且规定‘#’的优先级最低。

在输入表达式的最后输入‘#’,代表表达式输入结束。

在表达式输入过程中,遇操作数则直接入栈。

遇到运算符则与栈顶运算符比较优先级,当前运算符优先级高(前面的运算还不应执行)则当前运算符入栈,扫描下一符号;否则栈顶运算符出栈,两操作数出栈,进行运算,所得结果入数栈,重新比较当前运算符(注意当前运算符未变)与新栈顶运算符。

如此重复直到栈顶运算符与当前符号均为‘#’,运算结束。

(4)最初实现的加、减、乘、除及带小括号的基本运算,但考虑到实用性,后来的设计中有加上了乘方运算。

在乘方运算中借用了C库中自带的乘方函数pow。

二、概要设计1、设定栈的抽象数据类型定义:ADT Stack {数据对象:D={ ai | ai∈ElemSet, i=1,2,...,n,n≥0 }数据关系:R1={ <ai-1, ai >| ai-1, ai∈D, i=2,...,n }约定an端为栈顶,a1端为栈底。

基本操作:InitStack(&S)操作结果:构造一个空栈S。

DestroyStack(&S)初始条件:栈S已存在。

操作结果:栈S被销毁。

StackEmpty(S)初始条件:栈S已存在。

操作结果:若栈S为空栈,则返回TRUE,否则FALE。

StackLength(S)初始条件:栈S已存在。

操作结果:返回S的元素个数,即栈的长度。

GetTop(S, &e)初始条件:栈S已存在且非空。

操作结果:用e返回S的栈顶元素。

ClearStack(&S)初始条件:栈S已存在。

源代码--数据结构与算法(Python版)chap10 排序

源代码--数据结构与算法(Python版)chap10 排序
20
交换类
(2)快速排序 快速排序采用分而治之(Divide and Conquer)
的策略将问题分解成若干个较小的子问题,采用 相同的方法一一解决后,再将子问题的结果整合 成最终答案。快速排序的每一轮处理其实就是将 这一的基准数定位,直到所有的数都排序完成 为止。
21
快速排序的基本步骤:
1. 选定一个基准值(通常可选第一个元素); 2. 将比基准值小的数值移到基准值左边,形
14
• 交换类
交换类排序的基本思想是:通过交换无序序列 中的记录得到其中关键字最小或最大的记录,并将 其加入到有序子序列中,最终形成有序序列。交换 类排序可分为冒泡排序和快速排序等。
15
交换类
(1)冒泡排序 两两比较待排序记录的关键字,发现两
个记录的次序相反时即进行交换,直到没有 反序的记录为止。因为元素会经由交换慢慢 浮到序列顶端,故称之为冒泡排序。
3. 最后对这个组进行插入排序。步长的选法 一般为 d1 约为 n/2,d2 为 d1 /2, d3 为 d2/2 ,…, di = 1。
11
【例】给定序列(11,9,84,32,92,26,58,91,35, 27,46,28,75,29,37,12 ),步长设为d1 =5、d2 =3、 d3 =1,希尔排序过程如下:
for i in range(1,len(alist)):
#外循环n-1
for j in range(i,0,-1):
#内循环
if alist[j]<alist[j-1]:
alist[j],alist[j-1]=alist[j-1],alist[j] #交换
li=[59,12,77,64,72,69,46,89,31,9] print('before: ',li) insert_sort(li) print('after: ',li)

数据结构课程设计代码

数据结构课程设计代码

数据结构课程设计代码根据提供的输入输出需求,下面是一个示例的数据结构课程设计代码。

```pythonclass Node:def __init__(self, data):self.data = dataself.next = Noneclass LinkedList:def __init__(self):self.head = Nonedef add(self, data):new_node = Node(data)if self.head is None:self.head = new_nodeelse:current = self.headwhile current.next is not None:current = current.nextcurrent.next = new_nodedef remove(self, data):current = self.headprev = Nonewhile current is not None:if current.data == data:if prev is None:self.head = current.next else:prev.next = current.next returnprev = currentcurrent = current.nextdef display(self):current = self.headwhile current is not None:print(current.data, end=" ")current = current.nextprint()if __name__ == "__main__":linked_list = LinkedList()while True:print("1. Add element")print("2. Remove element")print("3. Display elements")print("4. Quit")choice = input("Enter your choice: ")if choice == "1":data = input("Enter element to add: ")linked_list.add(data)elif choice == "2":data = input("Enter element to remove: ")linked_list.remove(data)elif choice == "3":linked_list.display()elif choice == "4":breakelse:print("Invalid choice")```这个代码示例实现了一个简单的链表数据结构,在命令行中提供了添加元素、删除元素和显示元素的选项。

数据结构课程设计源代码(完整版)

数据结构课程设计源代码(完整版)

算法与数据结构课程设计报告设计题目:专业班级学生学号指导教师2014年第1学期第一部分:需求分析1、系统名称:航空客运订票系统航空客运订票的业务活动包括:查询航线、客票预定和办理退票等。

要求在TC或VC环境下设计一个航空客运订票系统,以使上述业务可以借助计算机来完成。

2、要求:(1)每条航线所涉及的信息有:终点站名、航班号、飞机号、飞行日期(星期几)、乘员定额、余票量、已经订票的客户名单(包括姓名、订票量)以及等候替补的客户名单(包括姓名、所需票量)。

(2)作为模拟系统,全部数据可以只存放在内存中。

(3)通过此系统可以实现如下功能:①录入功能:可以录入航班情况②查询功能:根据客户提供的终点站名进行查询,可以输出以下信息:航班号、飞机号、星期几飞行和余票量等。

也可以根据航班号,查询飞机某个航线的情况。

③订票功能:根据客户提出的要求(姓名、终点站名、订票数量)查询该航班的余票量情况。

如尚有足够的余票,则为客户办理订票手续;若已满员或余票量少于订票数量,则需要重新询问客户要求,如需要,可登记排队候补。

④退票功能:根据客户提供的情况(姓名、日期、航班号),为客户办理退票手续,然后查询该航班是否有人排队候补,若有人排队,则为排在第一位的客户办理订票手续。

第二部分:系统设计图样一:设计说明1:添加航班:整个航班的信息保存在一个结构体flight中,采用结构体数组,每一个航班信息包含航班号、起飞时间、起飞城市、降落时间、降落城市、余票数量。

航班信息通过lulu()函数进行添加。

添加的信息保存在航班flight结构体数组中。

2:查询航班:查询板块分为两个部分,按姓名查找和按站名查找。

按姓名查找:通过所输入的姓名和已定客户的姓名相匹配,匹配成功则查找成功。

按站名查找:通过所输入的起始站名和终点站名进行匹配,匹配成功则查找成功。

3:订票功能:根据用户的姓名和航班号进行订票,如果所查找的航班号的余票满足用户需要的票数,则订票成功,该信息保存在Customer中,才用结构体数组,包含已定客户的姓名、客户ID、订的票数、起飞时间、起飞城市、降落时间、降落城市、航班号。

数据结构三元组c语言源代码

数据结构三元组c语言源代码

数据结构三元组c语言源代码数据结构三元组C语言源代码在计算机科学领域,数据结构是一种组织和存储数据的方式,它可以让我们更高效地管理和处理数据。

在数据结构中,三元组是一种常用的结构,它由三个元素组成,分别对应于一个事物的不同方面。

在C 语言中,我们可以使用结构体来实现三元组。

首先,我们需要定义一个结构体来表示三元组。

在下面的代码中,我们定义了一个名为`triple`的结构体,它有三个成员变量分别为`a`,`b`和`c`。

```ctypedef struct {int a;double b;char c;} triple;```这个结构体中,`a`表示整型变量,`b`表示双精度浮点型变量,`c`表示字符型变量。

我们可以根据需要更改这些类型,以便适应特定的数据需求。

接下来,我们可以使用三元组结构体来创建存储数据的具体实例。

在下面的代码片段中,我们定义了一个名为`example`的三元组,它的第一,二,三个元素分别为1、3.14和'A'。

```ctriple example = { 1, 3.14, 'A' };```我们还可以定义一个函数来根据用户提供的数据创建一个新的三元组实例。

在下面的代码片段中,我们创建了一个名为`create_triple`的函数,并定义一个名为`new_triple`的三元组变量,它的元素根据用户输入而定。

```ctriple create_triple() {triple new_triple;printf("请输入一个整数:");scanf("%d", &new_triple.a);printf("请输入一个双精度浮点数:");scanf("%lf", &new_triple.b);printf("请输入一个字符:");scanf(" %c", &new_triple.c);return new_triple;}```最后,我们可以在程序中使用定义好的结构体和函数来处理我们的数据。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实习报告实验名称:基本算法演示程序日期:2017年7月7日姓名:李琛学号:20153204 班级:信1501-2 指导教师:陈娜1.实验题目4、Prim 算法输入:无向图(顶点序列,边序列)功能要求:输出最小生成树的各组成边及最小生成树的权值5、Kruskal 算法输入:无向图(顶点序列,边序列)功能要求:输出最小生成树的各组成边及最小生成树的权值6、Floyd 算法输入:有向图(顶点序列,有向边序列)功能要求:输出各顶点对间最短路径和路径长度7、Dijkstra 算法输入:有向图(顶点序列,有向边序列),起始顶点功能要求:输出起始顶点到其它各顶点的最短路径和路径长度2.需求分析4、Prim 算法输入:无向图(顶点序列,边序列)功能要求:输出最小生成树的各组成边及最小生成树的权值5、Kruskal 算法输入:无向图(顶点序列,边序列)功能要求:输出最小生成树的各组成边及最小生成树的权值6、Floyd 算法输入:有向图(顶点序列,有向边序列)功能要求:输出各顶点对间最短路径和路径长度7、Dijkstra 算法输入:有向图(顶点序列,有向边序列),起始顶点功能要求:输出起始顶点到其它各顶点的最短路径和路径长度3.概要设计4、Prim 算法struct AMGraphp{VerTexType vexs[MVNum]; //顶点表ArcType arcs[MVNum][MVNum]; //邻接矩阵int vexnum, arcnum; //图的当前点数和边数};//Prim算法辅助结构体struct close{VerTexType adjvex;ArcType lowcost;};#define MaxInt 32767 //极大值#define MVNum 100 //最大顶点数typedef char VerTexType; //顶点类型为字符型typedef int ArcType; //边的权值为整型5、Kruskal 算法#define MaxInt 32767 //极大值#define MVNum 100 //最大顶点数typedef char VerTexType; //顶点类型为字符型typedef int ArcType; //边的权值为整型struct AMGraphk{VerTexType vexs[MVNum]; //顶点表ArcType arcs[MVNum][MVNum]; //邻接矩阵int vexnum, arcnum; //图的当前点数和边数};//kruskal算法辅助结构体struct Edge{VerTexType Head;VerTexType Tail;ArcType lowcost;};6、Floyd 算法#define MaxInt 32767 //极大值#define MVNum 100 //最大顶点数typedef char VerTexType; //顶点类型为字符型typedef int ArcType; //边的权值为整型int D[100][100], Path[100][100];struct AMGraphf{VerTexType vexs[MVNum]; //顶点表ArcType arcs[MVNum][MVNum]; //邻接矩阵int vexnum, arcnum; //图的当前点数和边数};7、Dijkstra 算法#define MaxInt 32767 //极大值#define MVNum 100 //最大顶点数typedef char VerTexType; //顶点类型为字符型typedef int ArcType; //边的权值为整型int S[100], D[100], min, Path[100];struct AMGraphd{VerTexType vexs[MVNum]; //顶点表ArcType arcs[MVNum][MVNum]; //邻接矩阵int vexnum, arcnum; //图的当前点数和边数};函数曾今调用关系4.详细设计Head.h#pragma once#include<iostream>#include<string>using namespace std;//图的邻接矩阵存储表示#define MaxInt 32767 //极大值#define MVNum 100 //最大顶点数typedef char VerTexType; //顶点类型为字符型typedef int ArcType; //边的权值为整型void prim();void kruskal();void dijkstra();void floyd();Main.cpp#include"head.h"void main(){int a=1;cout <<"请输入想要运行的算法序号:"<<endl;cout <<"1、prim算法"<<endl;cout <<"2、kruskal算法"<< endl;cout <<"3、dijkstra算法"<< endl;cout <<"4、floyd算法"<< endl;while (a != 0){cout <<"请输入:";cin >> a;switch (a){case 1:prim(); break;case 2:kruskal(); break;case 3:dijkstra(); break;case 4:floyd(); break;}}}Prim.cpp#include"head.h"struct AMGraphp{VerTexType vexs[MVNum]; //顶点表ArcType arcs[MVNum][MVNum]; //邻接矩阵int vexnum, arcnum; //图的当前点数和边数};//Prim算法辅助结构体struct close{VerTexType adjvex;ArcType lowcost;};int LocateVex(AMGraphp G, VerTexType u){int i = 0;while (G.vexs[i] != u) i++;return i;}//使用邻接矩阵表示法创建无向图int CreateUDN(AMGraphp &G){int i, j, k,w;char v1, v2;cout <<"输入顶点数和边数:";cin >>G.vexnum >>G.arcnum; //输入总顶点数,总边数for (i = 0; i < G.vexnum; ++i) //依次输入点的信息{cout <<"输入第";cout << i+1;cout <<"顶点信息:";cin >>G.vexs[i];}for (i = 0; i < G.vexnum; ++i) //权值初始化为最大值for (j = 0; j < G.arcnum; ++j)G.arcs[i][j]=MaxInt;for (k = 0; k < G.arcnum; ++k) //构造邻接矩阵{cout <<"输入边的两点信息:"; //输入两点信息cin >> v1 >> v2;i = LocateVex(G, v1);j = LocateVex(G, v2);cout <<"输入权值:"; //输入权值cin >> w;G.arcs[i][j] = w;G.arcs[j][i] = G.arcs[i][j];}return 0;}//Prim算法最小生成树的构造void MinispanTree_prim(AMGraphp G, int a, AMGraphp &T){int k = a-1, i, j, m, lowcost;//规定从第a个顶点开始close closedge[100];//辅助数组的声明T.vexnum = G.vexnum; //T的初始化for (i = 0; i<G.vexnum; i++)T.vexs[i] = G.vexs[i];for (i = 0; i<G.vexnum; i++)for (j = 0; j<G.vexnum; j++)T.arcs[i][j] = -1;for (i = 0; i<G.vexnum; i++){closedge[i].adjvex = k;closedge[i].lowcost = G.arcs[k][i];}closedge[k].lowcost = 0;//把第0个结点并入最小生成树for (m = 1; m<G.vexnum; m++){lowcost = MaxInt;for (i = 1; i<G.vexnum; i++){if (lowcost>closedge[i].lowcost&&closedge[i].lowcost != 0 && closedge[i].lowcost != -1){lowcost = closedge[i].lowcost;k = i;}}T.arcs[closedge[k].adjvex][k] = lowcost;//在T中存最小生成树的边T.arcs[k][closedge[k].adjvex] = lowcost;closedge[k].lowcost = 0;//把第k个结点并入最小生成树for (i = 1; i<G.vexnum; i++){if ((G.arcs[k][i]<closedge[i].lowcost&&G.arcs[k][i] != -1) || closedge[i].lowcost == -1){closedge[i].lowcost = G.arcs[k][i];closedge[i].adjvex = k;}}}}//邻接矩阵输出void AMGout(AMGraphp T){int i ,j,k;cout <<"点的信息分别为:"<<endl;for (i = 0; i < T.vexnum; i++)cout <<T.vexs[i]<<" ";cout << endl;cout <<"邻接矩阵为:"<< endl;for (j = 0; j < T.vexnum; j++){for (k = 0; k < T.vexnum; k++){if (T.arcs[j][k] >= 32767 || T.arcs[j][k]<0)cout <<"*"<<" ";elsecout <<T.arcs[j][k] <<" ";}cout << endl;}}//调用函数void prim(){AMGraphp M;AMGraphp N;CreateUDN(M);AMGout(M);int a;cout <<"请输入开始的点:";cin >> a;MinispanTree_prim(M, a, N);cout <<"最小生成树为:"<<endl;AMGout(N);}Kruskal.cpp#include"head.h"struct AMGraphk{VerTexType vexs[MVNum]; //顶点表ArcType arcs[MVNum][MVNum]; //邻接矩阵int vexnum, arcnum; //图的当前点数和边数};//kruskal算法辅助结构体struct Edge{VerTexType Head;VerTexType Tail;ArcType lowcost;};//顶点定位int LocateVex(AMGraphk G, VerTexType u){int i = 0;while (G.vexs[i] != u) i++;return i;}//创建无向图int CreateUD(AMGraphk &G){int i, j, k, w;char v1, v2;cout <<"输入顶点数和边数:";cin >>G.vexnum >>G.arcnum; //输入总顶点数,总边数for (i = 0; i < G.vexnum; ++i) //依次输入点的信息{cout <<"输入第";cout << i + 1;cout <<"顶点信息:";cin >>G.vexs[i];}for (i = 0; i < G.vexnum; ++i) //权值初始化为最大值for (j = 0; j < G.arcnum; ++j){G.arcs[i][j] = MaxInt;}for (k = 0; k < G.arcnum; ++k) //构造邻接矩阵{cout <<"输入边的两点信息:"; //输入两点信息cin >> v1 >> v2;i = LocateVex(G, v1);j = LocateVex(G, v2);cout <<"输入权值:"; //输入权值cin >> w;G.arcs[i][j] = w;G.arcs[j][i] = G.arcs[i][j];}return 0;}int Vexset[MVNum];void kruskal(){Edge a[100];AMGraphk G;CreateUD(G);int i, j, k = 0;for (i = 0; i < G.arcnum; i++){for (j = i+1; j < G.arcnum; j++){if (G.arcs[i][j] > 0 && G.arcs[i][j]<MaxInt){a[k].Head = G.vexs[i];a[k].Tail = G.vexs[j];a[k].lowcost = G.arcs[i][j];k++;}}}int v1, v2, vs1, vs2;Edge b;for (i = 0; i < G.arcnum; i++){for (j = i+1; j < G.arcnum; j++){if (a[i].lowcost > a[j].lowcost){b = a[i];a[i] = a[j];a[j] = b;}}}for (i = 0; i < G.vexnum; i++){Vexset[i] = i;}for (i = 0; i < G.arcnum; i++){v1 = LocateVex(G, a[i].Head);v2 = LocateVex(G, a[i].Tail);vs1 = Vexset[v1];vs2 = Vexset[v2];if (vs1 != vs2){cout << a[i].Head <<" "<< a[i].Tail << endl;for (j = 0; j < G.vexnum; j++){if (Vexset[j] == vs2)Vexset[j] = vs1;}}}}Dijkstra.cpp#include"head.h"int S[100], D[100], min, Path[100];struct AMGraphd{VerTexType vexs[MVNum]; //顶点表ArcType arcs[MVNum][MVNum]; //邻接矩阵int vexnum, arcnum; //图的当前点数和边数};int LocateVex(AMGraphd G, VerTexType u){int i = 0;while (G.vexs[i] != u) i++;return i;}int CreateUD(AMGraphd &G){int i, j, k, w;char v1, v2;cout <<"输入顶点数和边数:";cin >>G.vexnum >>G.arcnum; //输入总顶点数,总边数for (i = 0; i < G.vexnum; ++i) //依次输入点的信息{cout <<"输入第";cout << i + 1;cout <<"顶点信息:";cin >>G.vexs[i];}for (i = 0; i < G.vexnum; ++i) //权值初始化为最大值for (j = 0; j < G.vexnum; ++j){G.arcs[i][j] = MaxInt;}for (k = 0; k < G.arcnum; ++k) //构造邻接矩阵{cout <<"输入边的两点信息:"; //输入两点信息cin >> v1 >> v2;i = LocateVex(G, v1);j = LocateVex(G, v2);cout <<"输入权值:"; //输入权值cin >> w;G.arcs[i][j] = w;}return 0;}void dijkstra(){AMGraphd G;CreateUD(G);int i,n, v, v0,w;cout <<"请输入起始点:"<< endl;cin >> v0;v0 = v0 - 1;n = G.vexnum;for (v = 0; v < n; v++){S[v] = false;D[v] = G.arcs[v0][v];if (D[v] < MaxInt)Path[v] = 0;elsePath[v] = -1;}S[v0] = true;D[v0] = 0;for (i = 1; i < n; i++){min = MaxInt;for (w = 0; w < n; w++){if (!S[w] && D[w] < min){v = w;min = D[w];}}S[v] = true;for (w = 0; w < n; w++){if (!S[w] && (D[v] + G.arcs[v][w] < D[w])){D[w] = D[v] + G.arcs[v][w];Path[w] = v;}}}int x = 0;cout <<"点到各点的最短路径长度"<< endl;while (S[x]){cout << D[x] <<" " ;x++;}cout << endl;x = 0;cout <<"各终点的前驱点"<< endl;while (S[x]){cout << Path[x]+1 <<" ";x++;}cout << endl;}Floyd.cpp#include"head.h"int D[100][100], Path[100][100];struct AMGraphf{VerTexType vexs[MVNum]; //顶点表ArcType arcs[MVNum][MVNum]; //邻接矩阵int vexnum, arcnum; //图的当前点数和边数};int LocateVex(AMGraphf G, VerTexType u){int i = 0;while (G.vexs[i] != u) i++;return i;}int CreateUD(AMGraphf &G){int i, j, k, w;char v1, v2;cout <<"输入顶点数和边数:";cin >>G.vexnum >>G.arcnum; //输入总顶点数,总边数for (i = 0; i < G.vexnum; ++i) //依次输入点的信息{cout <<"输入第";cout << i + 1;cout <<"顶点信息:";cin >>G.vexs[i];}for (i = 0; i < G.vexnum; ++i) //权值初始化为最大值for (j = 0; j < G.arcnum; ++j){G.arcs[i][j] = MaxInt;}for (k = 0; k < G.arcnum; ++k) //构造邻接矩阵{cout <<"输入边的两点信息:"; //输入两点信息cin >> v1 >> v2;i = LocateVex(G, v1);j = LocateVex(G, v2);cout <<"输入权值:"; //输入权值cin >> w;G.arcs[i][j] = w;}return 0;}void floyd(){AMGraphf G;CreateUD(G);int i, j, k;for ( i = 0; i < G.vexnum; i++){for ( j = 0; j < G.vexnum; j++){D[i][j] = G.arcs[i][j];if (D[i][j] < MaxInt) Path[i][j] = i;else Path[i][j] = -1;}}for ( k = 0; k < G.vexnum; k++){for ( i = 0; i < G.vexnum; i++){for ( j = 0; j < G.vexnum; j++){if (D[i][k] + D[k][j] < D[i][j]){D[i][j] = D[i][k] + D[k][j];Path[i][j] = Path[k][j];}}}}for (i = 0; i < G.vexnum; i++){for ( j = 0; j < G.vexnum; j++){if (D[i][j] == MaxInt)cout <<"*"<<" ";elsecout << D[i][j] <<" ";}cout << endl;}for (i = 0; i < G.vexnum; i++){for (j = 0; j < G.vexnum; j++){if (Path[i][j] == -1)cout <<"#"<<" ";elsecout << Path[i][j] +1<<" ";}cout << endl;}cout <<"请输入始终点:"<< endl;int a, b;cin >> a >> b;cout <<"中间的路径点为:"<< endl;while(b>1){cout << Path[a][b] <<" ";b = Path[a][b];}}5.调试分析调试过程中出现了很比较多的问题,基本是课本上的代码出现的未知函数6.使用说明在主菜单中,输入1,2,3,4来选择算法,按照程序的提示来输入等候结果7.测试结果。

相关文档
最新文档