数据结构期末开卷考试,把ppt打印下来带进去看就行,但我们哪一届考的挺难,光看ppt不理解分应该不是很高(比如我...)
课件自取
链接:https://pan.baidu.com/s/17ptV57bn8N1cZfz_aUNnRg
提取码:ldn9
1.1 Set Operation(Chap 01)
计算集合的并、交和差并输出结果
输⼊格式
两⾏ ,第⼀⾏为集合a 第⼆⾏为集合b 集合的元素限定为⼩写字⺟字符['a',...,'z']
输出格式
⼀⾏,分别是集合a和集合b的并、交和差并输出结果(注意,每个输出结果按照'a' - 'z'升序排 列),如果输出结果为空,输出 '#'
样例输⼊
abc def
样例输出
abcdef # abc
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define maxsize 100//设置最大线性表的数据元素
typedef struct
{
char data[maxsize];
int length;
}Llist;
//创建一个空的集合
Llist* Createnull()
{
Llist *a= (Llist*)malloc(sizeof(Llist));
a->length = 0;
return a;
}
//数组转化为集合
Llist* Createset(char x[] , int y)
{
Llist *a= (Llist*)malloc(sizeof(Llist));
a->length = y;
int i=0;
for(i=0 ; i<y ; i++)
a->data[i]=x[i];
return a;
}
//定义Find函数 有相同返回1,没有相同返回0
int Find(Llist *L,char e)
{
int i=0;
for(i=0;i<L->length;i++)
{
if(L->data[i]==e)
return 1;
}
return 0;
}
//删除某一元素
void Delete(Llist *L,char e)
{
int i =0;
for(i=0;i<L->length;i++)
{
if(L->data[i]==e)
{
L->data[i]=L->data[--L->length];
return;
}
}
}
//输出线性表
void DispList(Llist *L)
{
int i,j;
char x;
for (i = 0; i <L->length-1; i++) {
for ( j = 0; j <L->length-1; j++) {
if (L->data[j]>L->data[j+1]>0) {
// 交换data[j]和data[j+1]:
x = L->data[j];
L->data[j] =L->data[j+1];
L->data[j+1] = x;
}
}
}
for(i=0;i<L->length;i++)
printf("%c",L->data[i]);
}
//求并集
void Union(Llist *a,Llist *b,Llist *c)
{
int i=0;
for(i=0 ;i<a->length;i++)
c->data[i] = a->data[i];
c->length=a->length;//把a的元素传递给c
for(i=0 ;i<b->length;i++)
{
if(!Find(c,b->data[i]))//判断重复
c->data[c->length++] =b->data[i];
}
}
//求交集
void Intersection(Llist *a,Llist *b,Llist *c)
{
c->length = 0;
int i;
for(i=0;i<a->length;i++)
{
if(Find(b,a->data[i]))//判断重复
c->data[c->length++] =a->data[i];
}
}
//求差集
void Difference(Llist *a,Llist *b,Llist *c)
{
int i=0,j = 0;
for (i=0;i<a->length;i++)
{
int k = 0;
for(j=0;j<b->length;j++)
{
if(b->data[j] == a->data[i])
k++;
}
if(k==0)
c->data[c->length++]=a->data[i];
}
}
int main()
{
char stra[maxsize]={0};//初始化数组
char strb[maxsize]={0};
scanf("%s",&stra);
scanf("%s",&strb);
int lena,lenb;
lena=strlen(stra);//求字符串a长度
lenb=strlen(strb);//求字符串b长度
Llist *s1,*s2,*s3,*s4,*s5;
//新建s1,s2,s3
s1 = Createset(stra , lena);
s2 = Createset(strb , lenb);
s3 = Createnull();//并集
s4 = Createnull();//交集
s5 = Createnull();//差集
Union(s1,s2,s3);
DispList(s3);//打印并集
if(s3->length==0)
printf("#");
printf(" ");
Intersection(s1,s2,s4);
DispList(s4);//打印交集
if(s4->length==0)
printf("#");
printf(" ");
Difference(s1,s2,s5);
DispList(s5);//打印差集
if(s5->length==0)
printf("#");
return 0;
}
1.2 Josephus Problem (Chap 02)
约瑟夫(Joseph)问题的⼀种描述是:编号为1,2,…,n的n个⼈按顺时针⽅向围坐⼀圈,每⼈持有⼀个 密码(正整数)。⼀开始任选⼀个正整数m,从第⼀个⼈开始按顺时针⽅向⾃1开始顺序报数,报到m时 停⽌报数。报m的⼈出列,从他在顺时针⽅向上的下⼀个⼈开始重新顺序报数从1报数到m出列,如此下 去,直⾄所有⼈全部出列为⽌。试设计⼀个程序求出出列顺序 使⽤单向循环链表结构实现
输⼊格式
1⾏,2个整数,中间由空格隔开 第⼀个整数表示n个⼈ 第⼆个整数表示m(提示:m可能会远⼤于n)
输出格式
⼀⾏,n个整数中间由空格隔开 数字表示离开圆圈的⼈的顺序
样例输⼊
6 5
样例输出
5 4 6 2 3 1
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct Node{
int number;
struct Node* next;
}Lnode,*List;
void CreateList(List L,int n)
{
List s,r;
r = L;
int i;
for(i = 2;i <= n;i++)
{
s = (List)malloc(sizeof(Lnode));
s->number = i;
r->next = s;
r = r->next;
}
r->next = L;
}
//循环删人
void Delete(List L,int n,int m)
{
int i = 1,j = 1,n1=n,m1=m;
List p,q,s;
p = L;
while(p->next != p)
{
m1 = m;
m1 = m1 % n1;
if(m1==0){
m1=n1;
}
while(j < m1)
{
q = p;
p = p->next;
j++;
}
s = p;
p = p->next;
q->next = p;
printf("%d ",s->number);
free(s);
j = 1;
n1=n1-1;
}
printf("%d",p->number);
}
int main()
{
int i , n , m ,x = 0;
List L = (List)malloc(sizeof(Lnode));
L->number = 1;
scanf("%d",&n);
scanf("%d",&m);
CreateList(L,n);
Delete(L,n,m);
return 0;
}
1.3 Calculator (Chap 03)
后缀表达式的计算规则是:从左向右扫描,遇到数字压栈,遇到操作符,弹出栈顶的两个元素,先弹出 的元素在右边,后弹出来的在左边,进⾏计算后,将结果压栈,再往后扫描,直到扫描结束,输出栈顶 元素,即为最终结果。 将中缀表达式转换为后缀表达式 并计算后缀表达式的值 使⽤栈实现
输⼊格式
1⾏
⼀个中缀表达式,包括+,-,*,/,(,)和数字(0-9整数), 总⻓度不超过200个字符 注1:表达式中不会出现负数(形如: -1+1)和负的表达式(形如:-(1+1),表达式⼀定合法,表达式中 间结果和最终结果均可以⽤double类型表示。 注2: 什么是合法的表达式:⾮0开头数字是合法的表达式(形如:1);表达式 运算符 表达式是合 法的表达式(形如:1+1);(表达式)是合法的表达式(形如:(1+1))
输出格式
2⾏
第⼀⾏给出转换后的后缀表达式,并且使⽤空格分隔每个数字和符号 第⼆⾏给出表达式的结果,保留3位⼩数
样例输⼊
2*(3+4)/5
样例输出
2 3 4 + * 5 /
2.800
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define maxsize 201
//char的栈
typedef struct Stack{
char* top;
char* base;
int size;
}Sqstack;
//初始化栈
void initStack(Sqstack* s)
{
s->base=(char*)malloc(maxsize*sizeof(char));
if(!s->base)
{
return;
}
s->top=s->base;
s->size=maxsize;
}
//入栈
void push(Sqstack* s,char e)
{
*(s->top)=e;
s->top++;
}
//出栈
void pop(Sqstack* s,char* e)
{
if(s->top == s->base)
{
return;
}
s->top--;
*e=*(s->top);
}
//将栈顶元素传到e中
void printtop(Sqstack s,char* e)
{
*e = *(s.top-1);
}
//double的栈
typedef struct dStack{
double* top;
double* base;
int size;
}Dsqstack;
//初始化栈
void DinitStack(Dsqstack* s)
{
s->base=(double*)malloc(maxsize*sizeof(double));
if(!s->base)
{
return;
}
s->top=s->base;
s->size=maxsize;
}
//入栈
void Dpush(Dsqstack* s,double e)
{
*(s->top)=e;
s->top++;
}
//出栈
void Dpop(Dsqstack* s,double* e)
{
if(s->top == s->base)
{
return;
}
s->top--;
*e=*(s->top);
}
double operation(char e,double x,double y)
{
switch(e){
case '+':
return x+y;
break;
case '-':
return x-y;
break;
case '*':
return x*y;
break;
case '/':
return x/y;
break;
}
}
int main()
{
double c=0,x=0,y=0;
char optop;//栈顶字符
char temp;//过渡变量 1*2+3-4/5*6
int a=1,postlen;
int exp_length=0,i=0,j=0,k=0;
char exp[100]={0};
char postexp[2*maxsize]={0};
char xtemp[maxsize]={0};
Sqstack op;//新建一个op栈
initStack(&op);
push(&op,'=');
Dsqstack st; //新建一个st栈
DinitStack(&st);
scanf("%s",&exp);
exp_length=strlen(exp);
//算数转后缀
for(i=0;i<exp_length;i++)
{
//exp是数字
if(exp[i]!='+' && exp[i]!='-' && exp[i]!='*' && exp[i]!='/' && exp[i]!='(' && exp[i]!=')')
{
postexp[j]=exp[i];
j++;
if(exp[i+1]>='0' && exp[i+1]<='9')
continue;
else
{
postexp[j]=' ';
j++;
}
}
//exp是运算符
else if(exp[i]=='(')
{
push(&op,exp[i]);
}
else if(exp[i]=='*'||exp[i]=='/')
{
printtop(op,&temp);
if(temp=='*'||temp=='/')
{
while(temp=='*'||temp=='/')
{
pop(&op,&temp);
postexp[j]=temp;
j++;
postexp[j]=' ';
j++;
printtop(op,&temp);
}
}
push(&op,exp[i]);
}
else if(exp[i]=='+'||exp[i]=='-')
{
printtop(op,&temp);
if(temp=='='||temp=='(')
{
push(&op,exp[i]);
}
else if(temp=='*'||temp=='/'||temp=='+'||temp=='-')
{
while(temp!='='&&temp!='(')
{
pop(&op,&temp);
postexp[j]=temp;
j++;
postexp[j]=' ';
j++;
printtop(op,&temp);
}
push(&op,exp[i]);
}
}
else if(exp[i]==')')
{
printtop(op,&temp);
while(temp!='(')
{
pop(&op,&temp);
postexp[j]=temp;
j++;
postexp[j]=' ';
j++;
printtop(op,&temp);
}
pop(&op,&temp);
}
}
printtop(op,&temp);
while(temp!='=')
{
pop(&op,&temp);
postexp[j]=temp;
j++;
postexp[j]=' ';
j++;
printtop(op,&temp);
}
postlen=j;
for(i=0;i<postlen;i++)
{
printf("%c",postexp[i]);
}
//运算
for(i=0;i<postlen;i++)
{
if(postexp[i]>='0'&&postexp[i]<='9')
{
xtemp[k]=postexp[i];
k++;
while(postexp[i+1]!=' ')
{
xtemp[k]=postexp[i+1];
k++;
i++;
}
c=atof(xtemp);
Dpush(&st,c);
memset(xtemp, 0,maxsize);//初始化中间过渡数组
k=0;
}
else if(postexp[i]==' ')
continue;
else
{
Dpop(&st,&y);
Dpop(&st,&x);
c=operation(postexp[i],x,y);
Dpush(&st,c);
}
}
Dpop(&st,&c);
printf("\n%.3f",c);
return 0;
}
第二阶段实验题目找不到了...只有代码了
2.1已知先序表达式和中序表达式求后序表达式
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
typedef struct TNode
{
int data;
struct TNode* left;
struct TNode* right;
};
typedef struct TNode* Tree;
Tree restoretree(int pre[], int in[], int n)
{
int i;
int lpre[MAX]={0}, rpre[MAX]={0};
int lin[MAX]={0}, rin[MAX]={0};
int x1=0,x2=0;
if (n == 0)
{
return NULL;
}
Tree T = (Tree)malloc(sizeof(struct TNode));
T->data = pre[0]; // 当前根节点
for(i=0;i<n;i++)
{
if(in[i]==pre[0]){
x1=i;
x2=n-x1-1;
break;
}
}
for (i = 0; i < n; i++)
{
if (i <= x1 && in[i] != pre[0])
lin[i] = in[i];
else
rin[i-x1-1] = in[i];
}
for (i = 1; i < n; i++)
{
if (i<(x1 + 1))
lpre[i-1] = pre[i];
else
rpre[i-x1-1] = pre[i];
}
T->left = restoretree(lpre, lin, x1);
T->right = restoretree(rpre, rin,x2 );
return T;
}
void Postorder(Tree t)
{
if(t != NULL){
Postorder(t->left);
Postorder(t->right);
printf("%d ",t->data);
}
}
int main()
{
int n=0,i=0;
int pre[MAX],in[MAX];
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&pre[i]);
for(i=0;i<n;i++)
scanf("%d",&in[i]);
Tree retree=NULL;
retree=restoretree(pre,in,n);
// printf("%d",retree->data);
Postorder(retree);
return 0;
}
这个写了两个代码,还有一个
#include <stdio.h>
#include <stdlib.h>
#define MAX 101
struct TNode
{
int data;
struct TNode* left;
struct TNode* right;
};
typedef struct TNode* Tree;
//重建树
Tree restoretree(int pre[], int in[], int n)
{
int i;
int lpre[MAX], rpre[MAX];
int lin[MAX], rin[MAX];
int a1 = 0, a2 = 0;
int b1 = 0, b2 = 0;
if (n == 0)
{
return NULL;
}
Tree T = (Tree)malloc(sizeof(struct TNode));
T->data = pre[0];
for (i = 0; i < n; i++)
{
if (i <= a1 && in[i] != pre[0])
{
lin[a1++] = in[i];
}
else if (in[i] != pre[0])
{
rin[a2++] = in[i];
}
}
for (i = 1; i < n; i++)
{
if (i<(a1 + 1))
lpre[b1++] = pre[i];
else
rpre[b2++] = pre[i];
}
T->left = restoretree(lpre, lin, a1);
T->right = restoretree(rpre, rin, a2);
return T;
}
//后序输出
void Postorder(Tree t)
{
if(t != NULL){
Postorder(t->left);
Postorder(t->right);
printf("%d ",t->data);
}
}
int main()
{
int n=0,i=0;
int pre[MAX],in[MAX];
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&pre[i]);
for(i=0;i<n;i++)
scanf("%d",&in[i]);
Tree retree=NULL;
retree=restoretree(pre,in,n);
Postorder(retree);
return 0;
}
2.2求外卖员的最短路径
#include<stdio.h>
#define SIZE 102
#define INF 1000000000
int map[SIZE][SIZE]; //邻接矩阵存储
int n=0,m=0,i,j,k;
int dijkstra(int to){ //从源点到目标点
int len[SIZE]; //d[i]表示源点到i这个点的距离
int visit[SIZE]; //节点是否被访问
int pos;
for(i = 1 ; i <= n ; i ++){ //初始化
visit[i] = 0; //一开始每个点都没被访问
len[i] = map[1][i]; //先假设源点到其他点的距离
}
for(i = 1 ; i < n ; ++i){ //对除源点的每一个点进行最短计算
int min = INF; //记录最小len[i]
//记录小len[i] 的点
for(j = 1 ; j <= n ; ++j){
if(!visit[j] && min > len[j]){
pos = j;
min = len[j];
}
}
visit[pos] = 1;
for(j = 1 ; j <= n ; ++j){
if(!visit[j] && (len[j] > (len[pos] +map[pos][j]))){ //如果j节点没有被访问过&&j节点到源节点的最短路径>pos节点到源节点的最短路径+pos节点到j节点的路径
len[j] = len[pos] + map[pos][j]; //更新j节点到源节点的最短路径
}
}
}
return len[to];
}
int main ()
{
int x[SIZE]={0};
int t=0;
while(1){
int i,j;
scanf("%d%d",&n,&m); //输入数据
if(n==0&&m==0)
break;
for(i = 0 ; i <n; i++){ //设一开始每个点都不可达
for(j = 0 ; j <n ; j++){
map[i][j] = INF;
}
}
int a,b,c; //输入数据
for(i = 0 ; i < m ; i++){
scanf("%d%d%d",&a,&b,&c);
map[a][b] = map[b][a] = c;
}
x[t]=dijkstra(n);
t++;
}
//按照格式加的....
if(t==0);
else if(t>0){
printf("%d",x[0]);
if(t>1)
{
for(i=1;i<t;i++)
printf("\n%d",x[i]);
}
}
return 0;
}
2.3二叉排序树,这个我记得oj贼严,怎么都过不了,最后好像老师降低了难度就过了:)
#include <stdlib.h>
#include <stdio.h>
#define MAX 1005
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode
{
int key;
int lay;//此节点所处的层数
BinTree left;
BinTree right;
};
//在二叉树中插入数据
BinTree insert(BinTree p, int k,int l)
{
l++;
if (p==NULL)
{
p = (BinTree)malloc(sizeof(struct TNode));
p->key = k;
p->lay = l;
p->left = p->right = NULL;
}
else
{
if (k < p->key)
{
p->left = insert(p->left, k , l); // 递归插入左子树
}
else if (k > p->key)
{
p->right = insert(p->right, k , l); // 递归插入右子树
}
}
return p;
}
总节点个数
//int size(BinTree p){
// if(p==NULL)
// return 0;
// return(1+size(p->left)+size(p->right));
//}
//求二叉树的高度 ,总层数
int height(BinTree p){
int l,r,h;
if(p){
l=height(p->left);
r=height(p->right);
h=l>r?l:r;
return h+1;
}
else
return 0;
}
// 输出每层节点个数
int print(BinTree p, int a,int c)
{
// int a1[MAX]={0};
if(p){
if(p->lay==a){
c++;
}
c=print(p->left,a,c);
c=print(p->right,a,c);
}
return c;
}
//输出查找长度
int search(BinTree T,int x){
BinTree p=T;
while(p){
if(x==p->key)
return p->lay;
else if(p->left==NULL&&x<p->key)
return p->lay+1;
else if(p->right==NULL&&x>p->key)
return p->lay+1;
else if(x<p->key)
p=p->left;
else if(x>p->key)
p=p->right;
}
}
int main()
{
BinTree T;
T = NULL;
int x,n,i,h,m;
int a[MAX]={0};
scanf("%d", &n);
for (i = 0; i<n; i++){
scanf("%d", &x);
T = insert(T , x , 0);
}
scanf("%d",&m);
for(i=0;i<m;i++){
scanf("%d",&a[i]);
}
h=height(T);
printf("%d\n",h);
for (i = 1; i<=h; i++){
printf("%d ",print(T,i,0));
}
for(i=0;i<m;i++){
printf("\n%d",search(T,a[i]));
}
return 0;
}
2.4三点中值法
#include <stdio.h>
void quickmid(int* num,int r){
if(r == 0)
{
return;
}
int k;
int i=0,j=r-1,t = 0;
int m=(j-i)/2;
int mid=median(num[i],num[j],num[m]);
if(r>0)
for(k=0;k<r;k++)
{
printf("%d ",num[k]);
}
if(r>0)
printf("-> ");
if(i<=j)
{
while(i<=j)
{
while(num[i]<mid)
i++;
while(num[j]>mid)
j--;
if(i<=j)
{
t = num[j];
num[j] = num[i];
num[i] = t;
i++;
j--;
}
}
}
if(r>0)
for(k=0;k<r;k++)
{
printf("%d",num[k]);
if(k!=r-1)
printf(" ");
else
printf("\n");
}
if(r>1)
{
quickmid(num,j+1);
quickmid(&num[i],r-i);
}
}
int median(int a,int b, int c){
int temp;
if (a>b){
temp=a;
a=b;
b=temp;
}
if (b>c){
temp=b;
b=c;
c=temp;
}
if (a>b){
temp=a;
a=b;
b=temp;
}
return b;
}
int main()
{
int n,i;
scanf("%d",&n);
int arr[n];
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
quickmid(arr,n);
for(i=0;i<n;i++)
printf("%d ",arr[i]);
return 0;
}