【数据结构】北邮国际学院大二下oj代码

数据结构期末开卷考试,把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;
}

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值