1、数据结构实验与实训教程程序代码(清华高职高职第 3 版)预备实验 复数 ADT 及其实现复数 ADT 实现的源程序#include #include /* 存储表示,结构体类型的定义 */typedef struct float x; /* 实部子域 */float y; /* 虚部的实系数子域 */ comp;/* 全局变量的说明 */comp a,b,a1,b1;int z;/* 子函数的原型声明 */void creat(comp *c);void outputc(comp a);comp add(comp k,comp h);/* 主函数 */main() creat( outputc
2、(a);creat( outputc(b);a1=add(a,b); outputc(a1); /* main */* 创建一个复数 */void creat(comp *c) float c1,c2;printf(“输入实部 real x=?“);scanf(“%f“,printf(“输入虚部 xvpu y=?“);scanf(“%f“,(*c).x=c1; c -y=c2; /* creat */* 输出一个复数 */void outputc(comp a) printf(“n %f+%f i nn“,a.x,a.y);/* 求两个复数相加之和 */comp add(comp k,comp
3、 h) comp l;l.x=k.x+h.x; l.y=k.y+h.y;return(l); /* add */实验 1 线性表的基本操作程序 1:题 1 线性表基本操作函数#include#include#includestruct LinearList *定义线性表结构*/int *list; /* 存线性表元素 */int size; /* 存线性表长度 */int MaxSize; /* 存 list 数组元素个数 */;typedef struct LinearList LIST;void InitList( LIST *L, int ms )/* 初始化线性表 */if( (L-l
4、ist = 1 ) = NULL ) printf( “内存申请错误!n“ );exit( 1 );2 L-MaxSize = ms;int InsertList( LIST *L, int item, int rc )/* item:记录值 rc:插入位置 */int i;if( 3 ) /* 线性表已满 */return -1;if( rc size;for( i = L-size - 1; i = rc; i- ) /* 将线性表元素后移 */5 L-listrc = item;L-size +;return 0; void OutputList( LIST *L ) /* 输出线性表元
5、素 */int i;for( i = 0; 6 i+ )printf( “%d “, L-listi );printf( “n“ );int FindList( LIST *L, int item ) /* 返回 =0 为元素位置 -1 没找到 */int i;for( i = 0; i size; i+ )if( 7 ) /* 找到相同的元素,返回位置 */return i;return -1; /* 没找到 */int DeleteList1( LIST *L, int item )/* 删除指定元素值的线性表记录,返回=0:删除成功 */int i, n;for( i = 0; i si
6、ze; i+ )if( item = L-listi ) /* 找到相同的元素 */break;if( i size ) for( n = i; n size - 1; n+ )L-listn = L-listn+1;L-size -;return i;return -1;int DeleteList2( LIST L, int rc ) /* 删除指定位置的线性表记录 */8 /*编写删除指定位置的线性表记录子程序*/程序 2:题 2 void main()LIST LL;int i, r;printf( “list addr=%ptsize=%dtMaxSize=%dn“, LL.list
7、, LL.size, LL.MaxSize );InitList( printf( “list addr=%ptsize=%dtMaxSize=%dn“, LL.list, LL.size, LL.MaxSize );while( 1 )printf( “请输入元素值,输入 0 结束插入操作:“ );fflush( stdin ); /* 清空标准输入缓冲区 */scanf( “%d“, if( 1 )break;printf( “请输入插入位置:“ );scanf( “%d“, InsertList( 2);printf( “线性表为: “ );3 while( 1 )printf( “请输
8、入查找元素值,输入 0 结束查找操作:“ );fflush( stdin ); /* 清空标准输入缓冲区 */scanf( “%d“, if( i = 0 )break;r = 4 if( r void del( int *A, int *n, int x, int y )int i, j;for( i = j = 0; i y | Ai #includetypedef struct list int data;struct list *next;LIST;void InitList( LIST *p ) /* 初始化链表 */1 /*编写初始化链表子程序 */void InsertList1
9、( LIST *p, int item, int rc )/* 向链表指定位置rc插入元素item */int i;LIST *u, *q, *r; /* u:新结点 q:插入点前驱 r:插入点后继 */u = ( LIST * )malloc( sizeof(LIST) );u-data = item;for( i = 0, r = *p ; 2 ; i+ ) q = r;r = r-next;if( 3 ) /* 插入首结点或 p 为空指针 */*p = u;else4 u-next = r;void InsertList2( LIST *p, int item )/* 向有序链表p插入键
10、值为item的结点 */LIST *u, *q, *r; /* u:新结点 q:插入点前驱 r:插入点后继 */u = ( LIST * )malloc( sizeof(LIST) );u-data = item;for( r = *p;5 /* 从链表首结点开始顺序查找 */if( r = *p ) /* 插入首结点或 p 为空指针 */6 elseq-next = u;u-next = r;/* 删除键值为item的链表结点 , 返回 0: 删除成功 1: 没找到 */int DeleteList( LIST *p, int item )LIST *q, *r; /* q:结点前驱 r:结
11、点后继 */q = *p; r=q;if( q = NULL ) /* 链表为空 */return 1;if( q-data = 7 ) /* 要删除链表首结点 */*p = q-next; /* 更改链表首指针 */8 /* 释放被删除结点的空间 */return 0; /* 删除成功 */for( ; 9 r = q, q = q-next ); /* 寻找键值为 item的结点 */if( q-data = item ) /* 找到结点 */r-next=q-next; /* 被删结点从链表中脱离 */free( q ); /* 释放被删除结点的空间 */return 0; /* 删除成
12、功 */return 1; /* 没有指定值的结点, 删除失败 */* 查找键值为item的链表结点位置 , 返回=1: 找到 -1: 没找到 */int FindList( LIST *p, int item )int i;for( i = 1; p-data != item 11 , i+ ); /* 查找键值为 item的结点 */return ( p = NULL ) ? -1 : i; /* 找到返回i */void OutputList( LIST *p ) /* 输出链表结点的键值 */while( 12 ) printf( “%4d“, p-data );p = p-next;
13、 /* 遍历下一个结点 */void FreeList( LIST *p ) /* 释放链表空间 */LIST *q, *r;for( q = *p; q != NULL; ) 13 q = q-next;14 *p = NULL; /* 将链表首指针致空 */程序 2:题 2void main()LIST *p;int op, i, rc;InitList( /* 初始化链表 */while( 1 )printf( “请选择操作 1:指定位置追加 2: 升序追加 3: 查找结点n“ );printf( “ 4: 删除结点 5: 输出结点 6: 清空链表 0:退出n“ );fflush( st
14、din ); /* 清空标准输入缓冲区 */scanf( “%d“, switch( op ) case 0: /* 退出 */return -1;case 1: /* 指定位置追加结点 */printf( “请输入新增结点键值和位置:“ );scanf( “%d%d“, 1 ;break;case 2: /* 按升序追加结点 */printf( “请输入新增结点键值:“ );scanf( “%d“, InsertList2( break;case 3: /* 查找结点 */printf( “请输入要查找结点的键值:“ );scanf( “%d“, rc = 2 ;if( rc 0 )prin
15、tf( “ 位置为%dn“, rc );elseprintf( “ 没找到n“ );break;case 4: /* 删除结点 */printf( “请输入要删除结点的键值:“ );scanf( “%d“, rc = 3 ;if( rc = 0 )printf( “ 删除成功n“, rc );elseprintf( “ 没找到n“ );break;case 5: /* 输出结点 */printf( “n 链表内容为:n“ );4 ;break;case 6: /* 清空链表 */5 ;break;程序 3:题 3#include#includetypedef struct node int x
16、;struct node *next;NODE;void input( NODE *a )NODE *p, *q;int i;printf( “请输入链表的元素,-1表示结束n“ );*a = NULL;while( 1 ) scanf( “%d“, if( i = -1 )break;p = ( NODE * )malloc( sizeof(NODE) );p-x = i;p-next = NULL;if( *a = NULL )*a = q = p;else q-next = p;q = q-next; void output( NODE *a )int i;for( i = 0; a !
17、= NULL; i+, a = a-next ) printf( “%7d“, a-x );if( ( i + 1 ) % 10 = 0 )printf( “n“ );printf( “n“ );void disa( NODE *a, NODE *b )NODE *r, *p, *q;p = a;r = *b = ( a = NULL ) ? NULL : a-next; / 如果链表a为空,则链表b也为空while( 1 / q指向偶数序号的结点3 / 将q从原a链表中删除r-next = q; / 将q结点加入到b链表的末尾4 / r指向b链表的最后一个结点p = p-next; / p指
18、向原a链表的奇数序号的结点r-next = NULL; / 将生成b链表中的最后一个结点的next域置空void main()NODE *a, *b;input( printf( “链表a的元素为:n“ );output( a );5 printf( “链表a的元素(奇数序号结点)为:n“ );output( a );printf( “链表b的元素(偶数序号结点)为:n“ );output( b );实验 3 栈的基本操作程序 1:题 1 栈的基本操作函数#include#define MAXN 10 /* 栈的最大容量 */* 定义栈的类型为 int */int push( int *sta
19、ck, int maxn, int *toppt, int x ) /* 进栈函数 */if( *toppt = maxn ) /* 1 */return 1; 2 /* 元素进栈 */+(*toppt); /* 栈顶指针+1 */return 0; /* 进栈成功 */int pop( int *stack, int *toppt, int *cp ) /*出栈函数*/if(3) /* 栈空,出栈失败,返回 1 */return 1;-(*toppt); /* 栈顶指针-1 */4return 0; /* 出栈成功 */void OutputStack( int *stack, int to
20、ppt ) /* 输出栈元素 */int i;for( i =5 ; i = 0; i- )printf( “%d “, stacki );printf( “n“ );程序 2:题 2 主函数void main()int sMAXN, i; /* 定义栈 */int top = 0; /* 设置为空栈 */int op;while( 1 )printf( “请选择操作,1:进栈 2:出栈 0:退出 “ );fflush( stdin ); /* 清空标准输入缓冲区 */scanf( “%d“, switch( op ) case 0: /* 退出 */return;case 1: /* 进栈
21、*/printf( “请输入进栈元素:“ );scanf( “%d“, if(1) /* 进栈成功 */printf( “进栈成功,栈内元素为:n“ );OutputStack( s, top );elseprintf( “栈满n“ );break;case 2: /* 出栈 */if(2) /* 出栈成功 */printf( “出栈元素为: %d , 栈内元素为:n“ , i );3 elseprintf( “栈空n“ );break;程序 3:题 3 配对函数int correct( char *exp, int max ) /* 传入参数为表达式、表达式长度,返回 0:成功,返回 1:错
22、误*/int flag = 0; /* 括号匹配标志,0: 正确 */char sMAXN; /* 定义栈 */int top = 0; /* 栈指针为 0,表示空栈 */char c;int i;for( i = 0;1; i+ ) /* 循环条件为表达式未结束且括号匹配 */if( expi=( | expi= | expi= push( s, MAXN, if( expi=) | expi= | expi= ) /* 遇到, 出栈 */2 /* 置出栈结果, 栈空出错 */if( ( expi=) if(3) /* 栈不为空,表明还有(,符号没匹配 */flag = 1;return f
23、lag;void main()char sMAXN, c; /* 定义栈 */char exp1024;int top = 0; /* 设置为空栈 */while( 1 ) printf( “请输入表达式, 输入 0 退出: “ );gets( exp ); /* 从标准输入中读取表达式 */expMAXN = 0; /* 表达式长度 #include#define MAXN 100 /* 栈的最大容量 */int pushc( ) /* char 型元素进栈函数 */*编写进栈子程序*/int popc( char *stack, int *toppt, char *cp ) /* char
24、 型元素出栈函数 */*编写出栈子程序*/int eval( ) /* 算术运算 */*编写算术运算子程序*/int operate( char *str, int *exp ) /* 计算后缀表达式的值 , 返回 0:成功 -1:表达式错误 -2:栈满 */char c;int opd1, opd2, temp, c1;int sMAXN;int i;int top = 0;for( i = 0; stri != 0; i+ )c = stri;if( c = 0 pushc( s, MAXN, /* +,-符号入栈 */break;case *: /* 为*,/, 将栈顶*,/符号出栈,
25、存入数组 */case /:while( top0 sout off+ = c; /*这段循环如何用 if 语句实现? */pushc( s, MAXN, /* *,/符号入栈 */break;while( 6 ) /* 所有元素出栈, 存入数组 */sout off+ = c;sout off = 0; /* 加休止符 */return 0;void main()char *sin; /* 输入表达式指针, 中缀表示 */char *sout; /* 输出表达式指针, 后缀表示 */int i;sin = (char *)malloc( 1024 * sizeof(char) );sout
26、= (char *)malloc( 1024 * sizeof(char) );if( 7 ) printf( “内存申请错误!n“ );return;printf( “请输入表达式: “ );gets( sin );if( 8 ) /* 转换成功 */printf( “后缀表达式为:%sn“, sout );switch( 9 ) case 0:printf( “计算结果为: %dn“, i );break;case -1:printf( “表达式错误n“ );break;case -2:printf( “栈操作错误n“ );break;实验 4 队列的基本操作程序 1:题 1 链接队列的基
27、本操作函数#include#includetypedef struct queue /* 定义队列结构 */int data; /* 队列元素类型为 int */struct queue *link;QUEUE;void EnQueue( QUEUE *head, QUEUE *tail, int x ) /* 进队操作 */QUEUE *p;p = (QUEUE *)malloc( sizeof(QUEUE) );1 p-link = NULL; /* 队尾指向空 */if( *head = NULL ) /* 队首为空,即为空队列 */2 else (*tail)-link = p; /*
28、 新单元进队列尾 */*tail = p; /* 队尾指向新入队单元 */int DeQueue( QUEUE *head, QUEUE *tail, int *cp ) /* 出队操作 1:对空 */QUEUE *p;p = *head;if( *head = NULL ) /* 队空 */return 1;*cp = (*head)-data;*head = 3 if( *head = NULL ) /* 队首为空,队尾也为空 */*tail = NULL;free( p ); /* 释放单元 */return 0;void OutputQueue( QUEUE *head ) /* 输出
29、队列中元素 */while( 4 ) printf( “%d “, head-data );head = head-link;printf( “n“ );程序 2:题 2 主程序:void main()QUEUE *head, *tail;int op, i;head = tail = NULL; /* 1 */while( 1 )printf( “请选择操作,1:进队 2:出队 0:退出 “ );fflush( stdin ); /* 清空标准输入缓冲区 */scanf( “%d“, switch( op ) case 0: /* 退出 */return;case 1: /* 进队 */pr
30、intf( “请输入进队元素:“ );scanf( “%d“, 2 ;printf( “队内元素为:n“ );OutputQueue( head );break;case 2: /* 出队 */if( 3 = 0 ) /* 出队成功 */printf( “出队元素为: %d , 队内元素为:n“ , i );OutputQueue( head );elseprintf( “队空n“ );break;程序 3:题 3 环型队列的基本操作函数#include#include#define MAXN 11 /* 定义环行顺序队列的存储长度 */int EnQueue( int *queue, int
31、 maxn, int *head, int *tail, int x )/* 进队操作, 返回 1:队满 */if( 1 = *head ) /* 队尾指针赶上队首指针, 队满 */return 1;*tail = 2 /* 队尾指针+1 */queue*tail = x; /* 元素入对尾 */return 0;int DeQueue( int *queue, int maxn, int *head, int *tail, int *cp )/* 出队操作 返回 1:队空 */if( *head = *tail ) /* 队首=队尾, 表明队列为空 */return 1;*head = (
32、*head + 1 ) % maxn; /* 队首指针+1 */3 /* 取出队首元素 */return 0;void OutputQueue( int *queue, int maxn, int h, int t ) /* 输出队列中元素 */while( 4 ) /* */h = ( h + 1 ) % maxn;printf( “%d “, queueh );printf( “n“ );程序 4:题 4 主程序:void main()int qMAXN; /* 假设环行队列的元素类型为 int */int q_h=0, q_t=0; /* 初始化队首,队尾指针为 0 */int op,
33、i;while( 1 )printf( “请选择操作,1:进队 2:出队 0:退出 “ );fflush( stdin ); /* 清空标准输入缓冲区 */scanf( “%d“, switch( op ) case 0: /* 退出 */return;case 1: /* 进队 */printf( “请输入进队元素:“ );scanf( “%d“, if( 1 != 0 )printf( “队列满n“ );else printf( “入队成功, 队内元素为:n“ );OutputQueue( q, MAXN, q_h, q_t );break;case 2: /* 出队 */if( 2 =
34、0 ) /* 出队成功 */printf( “出队元素为: %d , 队内元素为:n“ , i );OutputQueue( q, MAXN, q_h, q_t );elseprintf( “队空n“ );break;程序 5:题 5 医务室模拟程序#include#include#includetypedef struct int arrive; /* 病人到达时间 */int treat; /* 病人处理时间 */PATIENT;typedef struct queue /* 定义队列结构 */PATIENT data; /* 队列元素类型为 int */struct queue *lin
35、k;QUEUE;void EnQueue( QUEUE *head, QUEUE *tail, PATIENT x ) /* 进队操作 */*编写进队操作子程序*/int DeQueue( QUEUE *head, QUEUE *tail, PATIENT *cp ) /* 出队操作 1:对空 */*编写出队操作子程序*/void OutputQueue( QUEUE *head ) /* 输出队列中元素 */while( 1 ) printf( “到达时间: %d 处理时间: %dn “, head-data.arrive, head-data.treat );head = head-lin
36、k;void InitData( PATIENT *pa, int n ) /* 生成病人到达及处理时间的随机数列 */int parr = 0; /* 前一个病人到达的时间 */int i;for( i = 0; i 20 | n 0)/* 病人到达时间与上次处理时间迟 */5 /* 累计医生等待时间 */nowtime = pi.arrive; /* 时钟推进 */6 /* 病人入队 */DeQueue( /* 出队一位病人 */7 /* 累计病人等待时间 */finish = nowtime + curr.treat; /* 当前病人处理结束时间 */while( i #include#
37、include#define DEMARK 5 /* 按第二批录用的扣分成绩 */typedef struct stu /* 定义招聘人员信息结构 */int no, total, z2, sortm, zi; /* 编号, 总成绩, 志愿, 排除成绩, 录取志愿号 */ struct stu *next;STU;typedef struct jobint lmt, count; /* 计划录用人数, 已录用人数 */STU *stu; /* 录用者有序队列 */JOB;STU *head=NULL, *over=NULL;int all;void OutPutStu( STU *p ) /*
38、 输出应聘人员有序队列中编号和成绩 */for( ; 1 ; p = p-next )printf( “%d(%d)t“, p-no, p-total );void FreeStu( STU *p ) /* 释放应聘人员空间 */STU *q;while( *p != NULL ) q = *p;2 free( q );void Insert( STU *p, STU *u ) /* 按排除成绩从大到小顺序插队 */STU *v, *q; /* 插队元素的前后元素指针 */for( q = *p; q != NULL; v = q, q = q-next )if( 3 ) /* 队中工人成绩n
39、ext = q; /* 新元素的后继元素指针 */int InitJob( JOB *h, int n, int *all ) /* 随机生成工种信息 */int i;JOB *p;*all = 0;printf( “工种信息工种号(计划招聘人数)n“ );if( ( p = ( JOB * )malloc( n * sizeof( JOB ) ) ) = NULL ) printf( “内存申请错误!n“ );return -1;for( i = 0; i no = i;p-total = p-sortm = random( 201 );p-z0 = random( m ); /* 应聘人员
40、第一志愿 0 m-1 */p-z1 = random( m ); /* 应聘人员第二志愿 0 m-1 */p-zi = 0; /* 录取志愿初始化为 0, 即第一志愿 */printf( “%d,%3d,%d,%dt“, i, p-total, p-z0, p-z1 );Insert( h, p );printf( “n“ );return 0;void main()int m; /* 工种总数, 编号为 0 M-1 */int n; /* 应聘人员总数 */JOB *rz;int all; /* 计划招聘人员总数 */STU *head=NULL, *over=NULL; /* 应聘人员队列
41、, 落聘人员队列 */STU *p;int i;while( 1 )m = n = 0;printf( “请输入工种总数(120),= 0:退出 “ );scanf( “%d“, if( m = 0 ) /* 退出 */return;if( m 20 | m 400 ) free( rz ); /* 释放工种信息空间 */ continue;if( 6 != 0 ) /* 生成应聘人员信息 */return;printf( “n 应聘人员队列n“ );OutPutStu( head );While( 7 ) /* 当人员没招满且队列不为空 */p = head; /* 取应聘人员队首指针 */
42、head = head-next; /* 队首指针下移 */i = p-z p-zi ; /* 取该应聘人员的应聘工种号 */if( rzi.count zi = 1 ) p-next = over; /* 该工人入落聘者队列 */over = p;continue;p-sortm -= DEMARK; /* 该工种已招满, 工人分数降档 */p-zi = 1; /* 该工人改为第二志愿 */9 /* 10 */for( i = 0; i #define MAX 20void main()int i;int fibMAX;fib0 = 0;fib1 = 1;for( i = 2; i #def
43、ine MAX 5void main()int i, j, n = 1;int aMAXMAX;for( i = 0; 1 ;i+ )for( j = 0; j #include#define MIN 0.00005 /* 定义近似于 0 的值 */* 已知两多项式的系数和幂次, 返回最大公因式的幂次, 在*q 中得到系数表的首指针 */int Remainder( double *pa, int an, double *pb, int bn, double *q )double x, *temp;int k, j;if( an -MIN pb +;if( *pb -MIN /* 请注意浮点型
44、变量的判断为零方式 */if( bn = 0; i- ) printf( “请输入多项式%s%d 次幂的系数 “, note, i );scanf( “%lf“, pa+i );*p = pa;return 0; void Print( double *q, int n ) /* 输出最大公因式表达式 */int i;for( i = n; i = 1; i- )if( qi MIN | qi MIN | q0 #include /* 简单模式匹配算法 */int simple_match( char *t, char *p )int n, m, i, j, k;n = strlen( t )
45、;m = strlen( p );for( j = 0; 1 ; j+ ) /* 顺序考察从 tj开始的子串 */for( i = 0; 2 ; i+ ); /* 从 tj开始的子串与字符串 p 比较 */if( i = m ) /* 匹配成功 */return 0;return 1; /* 匹配失败 */void main()char *s1= “Abcabc“, “Abc123ab“, “eeefffg“ ;char *s2= “aBc“, “c123“, “fge“ ;int i;for( i = 0; i #include int commstr( char *str1, char *
46、str2, int *lenpt )int len1, len2, ln, count, i, k, p;char *st, form20;if( (len1=strlen(str1) 0; ln- ) /* 找长为 ln 的公共子串 */for( k = 0; 2 ; k+ ) /* 自 str2k开始的长为 ln 的子串与 str1 中的子串比较 */for( p = 0; p + ln #include /* 正文排版输出函数 s:预处理后的正文 nw:单词个数 sl:单词在 s 中的起始位置 sn:单词长度 */void paiban( char *s, int nw, int *sl, int *sn )int i, j, n, k, lnb, ln, m, ln1, lnw;char info81;ln = sn0; /* 一行中单词长度之和(包括每个单词间的一个空格) */for( i=1,j=0; i nw; i+ ) /* 循环输出至最后一行前 */ln1 = ln + 1 + sni;if( 1 )ln = ln1;else