SCAU2025数据结构(仅含实验题)oj全攻略

还是纯代码版+简化,适合考前速切。

本篇文章有结合网上其他的题解,会给出出处说明,侵删。

附考试原题题纲

目录

实验一

8576 顺序线性表的基本操作

8577 合并顺序表

8578 顺序表逆置

8579 链式线性表的基本操作

8580 合并链表

19080 反转链表

实验二

8583 顺序栈的基本操作

8584 循环队列的基本操作 

8585 栈的应用——进制转换

8586 括号匹配检验

8587 行编辑程序

(不抽考)8588 表达式求值

18938 汉诺塔问题

(不抽考)8590 队列的应用——银行客户平均等待时间

18937 阿克曼(Ackmann)函数

实验三

8591 计算next值

8592 KMP算法

(不抽考)18722 稀疏矩阵的运算

18769 不完整的排序

实验四

8606 二叉树的构建及遍历操作

17121 求二叉树各种节点数

18924 二叉树的宽度

18724 二叉树的遍历运算

18923 二叉树的直径

(不抽考)8609 哈夫曼树

实验五

8610 顺序查找

8621 二分查找

8622 哈希查找

(!该题作为综合性实验,为防止直接抄袭,将在上交截止后更新)(不抽考)8608 实现二叉排序树的各种算法(2)

实验六

8639 折半插入排序、8639 折半插入排序

8640 希尔(shell)排序

8641 冒泡排序

8642 快速排序

8643 简单选择排序

8644 堆排序 

8645 归并排序(非递归算法) 

(不抽考)8646 基数排序

实验七 

8647 实现图的存储结构

8648 图的深度遍历、8649 图的广度遍历

(不抽考)18448 最小生成树

(不抽考)18732 最短路问题

(不抽考)18734 拓扑排序

(不抽考)18747 关键路径

2025春数据结构期末考第三题


实验一

8576 顺序线性表的基本操作

首先复制题目中的代码(while(1)部分),然后在这个基础上进行修改即可。

#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;

int main(){
	vector<int> b;int i,x,e,a;
	printf("A Sequence List Has Created.\n");
	while(1)
	{
		printf("1:Insert element\n2:Delete element\n3:Load all elements\n0:Exit\nPlease choose:\n");
		scanf("%d",&a);
		switch(a)
		{
			case 1: scanf("%d%d",&i,&x);
					if(i<1||i>b.size()+1) printf("Insert Error!\n"); 
					else{
					b.insert(b.begin()+i-1,x);	
					printf("The Element %d is Successfully Inserted!\n", x); 	
					}
					break;
			case 2: scanf("%d",&i);
					if(i<1||i>b.size()) printf("Delete Error!\n"); 
					else{
						e=*(b.begin()+i-1);b.erase(b.begin()+i-1);
						printf("The Element %d is Successfully Deleted!\n", e);
					}
					break;
			case 3: if(b.empty()) cout<<"The List is empty!";
			        else{
			        	cout<<"The List is:";
			        	for(int i=0;i<b.size();i++) cout<<" "<<b[i];
					}
			        cout<<endl;
					break;
			case 0: return 1;
		}
	}
	return 0;
}

8577 合并顺序表

主打一个善用sort

#include<iostream>
#include<algorithm>
using namespace std;
int a[85],b[85],c[85];
int main(){
    int la,lb;
    cin>>la;
    for(int i=1;i<=la;i++){
        cin>>a[i];
        c[i]=a[i];
    }
    cout<<"List A:";
    for(int i=1;i<=la;i++){
            cout<<a[i]<<" ";
    }
    cout<<endl;
    cin>>lb;
    for(int i=1;i<=lb;i++){
        cin>>b[i];
        c[i+la]=b[i];
    }
    cout<<"List B:";
    for(int i=1;i<=lb;i++){
            cout<<b[i]<<" ";
    }
    cout<<endl;
    sort(c+1,c+1+la+lb);
    cout<<"List C:";
    for(int i=1;i<=la+lb;i++){
        cout<<c[i]<<" ";
    }
    return 0;
}

8578 顺序表逆置

顺着输入,再倒着输出(doge)

#include<iostream>

using namespace std;
int a[85];
int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	cout<<"The List is:";
	for(int i=1;i<=n;i++) cout<<a[i]<<" ";
	cout<<endl<<"The turned List is:";
	for(int i=n;i>=1;i--) cout<<a[i]<<" ";
	return 0;
}

8579 链式线性表的基本操作

和第一题(8576)差不多^-^

#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;

int main(){
	vector<int> b;int a,i,n,e,x;
	printf("Please input the init size of the linklist:\n");
	scanf("%d",&n);
    printf("Please input the %d element of the linklist:\n", n);
    for(int i=0;i<n;i++){
    	cin>>x;b.push_back(x);
	}
    printf("A Link List Has Created.\n");
    cout<<"The LinkList is:";for(int i=0;i<n;i++) cout<<b[i]<<" ";cout<<endl;
    while(1)
	{
		printf("1:Insert element\n2:Delete element\n3:Load all elements\n0:Exit\nPlease choose:\n");
		scanf("%d",&a);
		switch(a)
		{
			case 1: scanf("%d%d",&i,&x);
				  if(i<1||i>n+1) printf("Insert Error!\n"); 
				  else{
				  	b.insert(b.begin()+i-1,x);n++;
				  	printf("The Element %d is Successfully Inserted!\n", x);
				  } 
				  break;
			case 2: scanf("%d",&i);
				  if(i<1||i>=n) printf("Delete Error!\n"); 
				  else{
				  	e=b[i-1];b.erase(b.begin()+i-1);n--;
				  	printf("The Element %d is Successfully Deleted!\n", e);
				  }
				  break;
			case 3:if(b.empty()){
				       cout<<"The LinkList is empty!"<<endl;
			       }
			        else{
			           cout<<"The LinkList is:";for(int i=0;i<n;i++) cout<<b[i]<<" ";cout<<endl;	
			        }
				  break;
			case 0: return 1;
		}
	}
	return 0;
} 

8580 合并链表

和第二题(8577)一模一样

#include<iostream>
#include<algorithm>
using namespace std;
int a[85],b[85],c[85];
int main(){
    int la,lb;
    cin>>la;
    for(int i=1;i<=la;i++){
        cin>>a[i];
        c[i]=a[i];
    }
    cout<<"List A:";
    for(int i=1;i<=la;i++){
            cout<<a[i]<<" ";
    }
    cout<<endl;
    cin>>lb;
    for(int i=1;i<=lb;i++){
        cin>>b[i];
        c[i+la]=b[i];
    }
    cout<<"List B:";
    for(int i=1;i<=lb;i++){
            cout<<b[i]<<" ";
    }
    cout<<endl;
    sort(c+1,c+1+la+lb);
    cout<<"List C:";
    for(int i=1;i<=la+lb;i++){
        cout<<c[i]<<" ";
    }
    return 0;
}

19080 反转链表

要记得它有头结点捏

	LNode *p,*n;
	p=L->next;L->next=NULL;
	while(p){
		n=p->next;
		p->next=L->next;
		L->next=p;
		p=n;
	}

实验二

8583 顺序栈的基本操作

#include<iostream>
#include<stack>
#include<cstdio>

using namespace std;

int main(){
	printf("A Stack Has Created.\n");
	int a,x,e;stack<int> s;
while(1)
	{
    printf("1:Push \n2:Pop \n3:Get the Top \n4:Return the Length of the Stack\n5:Load the Stack\n0:Exit\nPlease choose:\n");
	scanf("%d",&a);
		switch(a)
		{
			case 1: scanf("%d", &x);s.push(x);
		      printf("The Element %d is Successfully Pushed!\n", x); 
		      break;
		case 2: if(s.empty()) printf("Pop Error!\n"); 
			  else{
			  	e=s.top();s.pop();
			  	printf("The Element %d is Successfully Poped!\n", e);
			  }
		  	  break;
		case 3: if(s.empty()) printf("Get Top Error!\n");
			  else{
			  	e=s.top();printf("The Top Element is %d!\n", e);
			  }
		   	  break;
			case 4: printf("The Length of the Stack is %d!\n",s.size());
				  break;
			case 5:if(s.empty()) cout<<"The Stack is Empty!"<<endl;
			      else{
			      	cout<<"The Stack is: ";
			      	stack<int> s1;
			        s1=s;
			        while(!s1.empty()){
			      	cout<<s1.top()<<" ";
			      	s1.pop();
				    }
				  cout<<endl;
				  }
				  break;
			case 0: return 1;
		}
	}	
	return 0;
}

8584 循环队列的基本操作 

#include<iostream>
#include<queue>
#include<cstdio>

using namespace std;

int main(){
	printf("A Queue Has Created.\n");
	int a,x,e;queue<int> q;
	while(1)
	{
	printf("1:Enter \n2:Delete \n3:Get the Front \n4:Return the Length of the Queue\n5:Load the Queue\n0:Exit\nPlease choose:\n");
		scanf("%d",&a);
		switch(a)
		{
			case 1: scanf("%d", &x);q.push(x);
				  printf("The Element %d is Successfully Entered!\n", x); 
				  break;
			case 2: if(q.empty()) printf("Delete Error!\n"); 
				  else{
				  	e=q.front();q.pop();
				  	printf("The Element %d is Successfully Deleted!\n", e);
				  }
				  break;
			case 3: if(q.empty())printf("Get Head Error!\n"); 
				  else{
				  	e=q.front();
				  printf("The Head of the Queue is %d!\n", e);
		        }
				  break;
			case 4: printf("The Length of the Queue is %d!\n",q.size()); 
				  break;
			case 5:if(q.empty()) cout<<"The Queue is Empty!"<<endl;
			else{
				printf("The Queue is: ");
				queue<int> q1=q;
				while(!q1.empty()){
					cout<<q1.front()<<" ";q1.pop();
				}
				cout<<endl;
			}
				  break;
			case 0: return 1;
		}
	}
	return 0;
}

8585 栈的应用——进制转换

#include<iostream>

using namespace std;

int main(){
	int n;cin>>n;
	printf("%o",n);
	return 0;
}

8586 括号匹配检验

#include <iostream>
#include <stack>

using namespace std;

int main() {
    string s;cin>>s;
    stack<char> ss;
    for(int i=0;i<s.length();i++){
        if(s[i]=='['||s[i]=='(') ss.push(s[i]);
        else if(s[i]==']'){
            if(ss.empty()){ cout << "lack of left parenthesis" << endl; return 0; }
            else if (ss.top() != '[') { cout << "isn't matched pairs" << endl; return 0;}
            else ss.pop();
        }
        else if(s[i]==')'){
            if(ss.empty()){ cout << "lack of left parenthesis" << endl; return 0; }
            else if(ss.top()!='('){ cout << "isn't matched pairs" << endl; return 0; }
            else ss.pop();
        }
        else continue;
    }
    if (ss.empty()) cout<<"matching";
    else cout << "lack of right parenthesis";
    return 0;
}

8587 行编辑程序

#include <iostream>
#include <stack>
#include<algorithm>
using namespace std;

int main() {
	int n;cin>>n;getchar();
	for(int i=1;i<=n;i++){
		string s;getline(cin,s);
		stack<char> ss;
		for(int j=0;j<s.length();j++){
			if(s[j]=='#') ss.pop();
			else if(s[j]=='@') while(!ss.empty()) ss.pop();
			else ss.push(s[j]);
		}
		string s1;
		while(!ss.empty()){
			s1+=ss.top();ss.pop();
		}
		reverse(s1.begin(),s1.end());
		cout<<s1<<endl;
	}
    return 0;
}

(不抽考)8588 表达式求值

#include <iostream>
#include <stack>
#include <ctype.h>
using namespace std;
char getp(char e,char c){
	switch(c){
		case'+':
		case'-':{
			if(e=='('||e=='=') return '<';
			else return '>';
		}
		case'*':
		case'/':{
			if(e=='*'||e=='/'||e==')') return '>';
			else return '<';
		}
		case'(':{
			if(e==')') return 0;
			else return '<';
		}
		case')':{
			if(e=='(') return '=';
			else if(e=='=') return 0;
			else return '>';
		}
		case'=':{
			if(e=='(') return 0;
			else if(e=='=') return '=';
			else return '>';
		}
	}
}
int main(){
	stack<double> shu;stack<char> fu;
	fu.push('=');
	char ch,e;
	ch=getchar();
	while(ch!='='||fu.top()!='='){
		double d=0;
		if(isdigit(ch)){
			while(isdigit(ch)){
			d=d*10+ch-'0';
			ch=getchar();
			}
			shu.push(d);
		}
		else{
			char n=getp(e,ch);
			if(n=='<'){
				fu.push(ch);
				ch=getchar();
			}
			else if(n=='='&&ch==')'){
				fu.pop();
				ch=getchar();
			}
			else if(n=='>'){
				double b=shu.top();
				shu.pop();
				double a=shu.top();
				shu.pop();
				fu.pop();
				if(e=='+') shu.push(a+b);
				else if(e=='-') shu.push(a-b);
				else if(e=='*') shu.push(a*b);
				else if(e=='/') shu.push(a/b);
			}
		}
		e=fu.top();
	}
	double ans=shu.top();
	cout<<ans;
	return 0;
} 

18938 汉诺塔问题

#include<iostream>

using namespace std;

void hano(char a,char c,char b,int x){
	if(x==1){
		cout<<a<<"->"<<1<<"->"<<b<<endl;
		return;
	}
	hano(a,b,c,x-1);
	cout<<a<<"->"<<x<<"->"<<b<<endl;
	hano(c,a,b,x-1);
}
int main(){
	int n;char a,b,c;
	cin>>n>>a>>b>>c;
	hano(a,c,b,n);
	return 0;
} 

(不抽考)8590 队列的应用——银行客户平均等待时间

#include<iostream>
#include<queue>
#include<cstdio>
using namespace std;

int main(){
	int n;cin>>n;
	queue<int> q;
	int sum=0,t=1;
	for(int i=1;i<=n;i++){
		int x,y;
		cin>>x>>y;
		if(t-x>=0) q.push(t-x);
		else{
			t=x;
		}
		t+=y;
	}
	while(!q.empty()){
		sum+=q.front();
		q.pop();
	}
	printf("%.2lf",sum*1.0/n);
	return 0;
}

18937 阿克曼(Ackmann)函数

#include<iostream>

using namespace std;
int akm(int m,int n){
	if(m==0) return n+1;
	else if(m>0&&n==0) return akm(m-1,1);
	else return akm(m-1,akm(m,n-1));
}
int main(){
	int m,n;cin>>m>>n;
	cout<<akm(m,n);
	return 0;
} 

实验三

8591 计算next值

#include<iostream>
using namespace std;
int nex[10005];
int main(){
	int n;cin>>n;
	while(n--){
		string s;cin>>s;s="0"+s;
		int j=0,i=1;
		while(i<s.length()){
			if(j==0||s[j]==s[i]){
				j++;i++;nex[i]=j;
			} 
			else j=nex[j];
		}
		cout<<"NEXT J is:";
		for(int i=1;i<s.length();i++) cout<<nex[i];
		cout<<endl;
	}
	return 0;
} 

8592 KMP算法

这里的写法有借鉴到SCAU期末笔记 - 数据结构(STL版)_8579链式线性表的基本操作scau-CSDN博客

#include<iostream>
#include<algorithm>
using namespace std;
int main(){
	int n;cin>>n;
	while(n--){
		string a,b;cin>>a>>b;
		cout<<a.find(b)+1<<endl;
	}
	return 0;
} 

(不抽考)18722 稀疏矩阵的运算

#include<iostream>
#include<algorithm>
using namespace std;
struct a{int h,l,x;};
struct a as[1000001];
int main(){
	int n,m,k;
	cin>>n>>m>>k;
	for(int i=1;i<=k;i++) cin>>as[i].l>>as[i].h>>as[i].x;
	sort(as+1,as+1+k,[](struct a&x,struct a&y){if(x.h!=y.h) return x.h<y.h;else return x.l<y.l;});
	for(int i=1;i<=k;i++) cout<<as[i].h<<" "<<as[i].l<<" "<<as[i].x<<endl;
	return 0;
}

18769 不完整的排序

#include<iostream>
#include<algorithm>
using namespace std;
int a[100001];
int main(){
	int t;cin>>t;
	while(t--){
		int n;cin>>n;
		for(int k=1;k<=n;k++) cin>>a[k];
		int i=1,j=n;
		while(i!=j){
			while(i<j&&a[i]<0) i++;
			while(j>i&&a[j]>0) j--;
			swap(a[i],a[j]); 
		}
		for(int k=1;k<=n;k++) cout<<a[k]<<" ";cout<<endl;
	}
	return 0;
}

实验四

8606 二叉树的构建及遍历操作

#include<iostream>
using namespace std;
int pos;string s;
void zhong(){
	char c=s[pos++];
	if(c!='#'){zhong();cout<<c;zhong();}
	else return;
}
void hou(){
	char c=s[pos++];
	if(c!='#'){hou();hou();cout<<c;}
	else return;	
}
int main(){
	cin>>s;
	for(int i=0;i<s.length();i++) if(s[i]!='#') cout<<s[i];
	cout<<endl;
	pos=0;zhong();cout<<endl;
	pos=0;hou();
	return 0;
} 

17121 求二叉树各种节点数

#include <iostream>
using namespace std;
int c0=0,c1=0,c2=0;
string s;

void count(int &i){
	if(i>=s.length()||s[i++]=='#') return;
	int l=i;count(i);int r=i;count(i);
	int c=(l<s.length()&&s[l]!='#')+(r<s.length()&&s[r]!='#');
	if(c==0) c0++;
	else if(c==1) c1++;
	else c2++;
}

int main(){
	cin>>s;int i=0;count(i);
	cout<<c2<<endl<<c1<<endl<<c0;
}

18924 二叉树的宽度

科研了几种方法都不太好,老实用回bfs了

#include <iostream>
#include<algorithm>
#include<queue>
using namespace std;
int t[51][2];
int main(){
	int n,x,y,maxx=0;cin>>n;
	for(int i=1;i<n;i++){
		cin>>x>>y;
		if(!t[x][0]) t[x][0]=y;
		else t[x][1]=y;
	}
	queue<int> q;q.push(1);
	while(!q.empty()){
		int l=q.size();
		maxx=max(l,maxx);
		for(int i=1;i<=l;i++){
			x=q.front();
			if(t[x][0]) q.push(t[x][0]);
			if(t[x][1]) q.push(t[x][1]);
			q.pop();
		}
	}
	cout<<maxx;
}

18724 二叉树的遍历运算

#include<iostream>
using namespace std;
string pre,in;
void p(int l1,int r1,int l2,int r2){
	char ch=pre[l1];
	if(l1>r1||l2>r2) return;
	int i;
	for(i=l2;i<=r2;i++) if(ch==in[i]) break;
	p(l1+1,r1-(r2-i),l2,i-1);
	p(r1-(r2-i)+1,r1,i+1,r2);
	cout<<ch;
}
int main(){
	cin>>pre>>in;
	int l1=pre.size()-1,l2=in.size()-1;
	p(0,l1,0,l2);
	return 0;
}

18923 二叉树的直径

#include<iostream>
using namespace std;
int t[51][2];
int ans=0;
int depth(int n){
	int ldep=0,rdep=0;
	if(t[n][0]) ldep=depth(t[n][0])+1;
	if(t[n][1]) rdep=depth(t[n][1])+1;
	ans=max(ans,ldep+rdep);
	return max(ldep,rdep);
}
int main(){
	int n;cin>>n;
	for(int i=1;i<n;i++){
		int x;cin>>x;
		if(!t[x][0]) cin>>t[x][0];
		else cin>>t[x][1];
	}
	depth(1);
	cout<<ans<<endl;
	return 0;
}

(不抽考)8609 哈夫曼树

#include "stdio.h"
#include "string.h"
#include<iostream>
using namespace std;
typedef struct
{
    unsigned int weight;
    unsigned int parent,lchild,rchild;
} HTNode,*HuffmanTree;
typedef char **HuffmanCode;
void   select(HuffmanTree &HT, int n, int &s1, int &s2)
{//在HT[1..n]中选择parent为0且weight最小的两个结点, 其序号分别为s1(最小)和s2(次小)。
    int s11=11111,s22=11111;
    for(int i=1;i<=n;i++){
    	if(!HT[i].parent&&HT[i].weight<s11){
    		s11=HT[i].weight;
    		s1=i;
		}
	}
    for(int i=1;i<=n;i++){
    	if(i!=s1&&!HT[i].parent&&HT[i].weight<s22){
    		s22=HT[i].weight;
    		s2=i;
		}
	}	
}
void createHuffmanTree(HuffmanTree &HT, int n)
{ //构造哈夫曼树HT
    int i, m, s1, s2;
    if (n<=1) return;
    m = 2 * n - 1;
    HT = new HTNode[m+1];  // 0号单元未用
    for (i=1; i<=m; i++) { //初始化HT数组
        HT[i].parent=0;HT[i].lchild=0;HT[i].rchild=0;
    }
    for (i=1; i<=n; i++)
        cin>>HT[i].weight;
    for (i=n+1; i<=m; i++)    // 建哈夫曼树
    { //在HT[1..i-1]中选择parent为0且weight最小的两个结点, 其序号分别为s1(最小)和s2(次小)
        	select(HT,i-1,s1,s2);
        	HT[s1].parent=i;
        	HT[s2].parent=i;
        	HT[i].lchild=s1;HT[i].rchild=s2;
        	HT[i].weight=HT[s1].weight+HT[s2].weight;
    }
}
void createHuffmanCode(HuffmanTree HT,HuffmanCode &HC,int n)
{//--- 从叶子到根逆向求每个字符的哈夫曼编码 ---
    char *cd = new char[n];    // 分配求编码的工作空间
    cd[n-1] = '\0';  // 编码结束符。
    int i,c,f,start;
    for (i=1; i<=n; ++i)
    {
        start = n-1;
        c=i, f=HT[i].parent;
        while(f)// 从叶子到根逆向求编码
        {
            --start;
            if (HT[f].lchild==c) cd[start] = '0';
            else cd[start] = '1';
            c=f,f=HT[f].parent;
        }
        HC[i] = new char[n-start];// 为第i个字符编码分配空间
        strcpy(HC[i], &cd[start]);    // 从cd复制编码(串)到HC
    }
}
int main()
{
    int i,n;
    int *w;
    HuffmanTree HT;
    HuffmanCode HC;
    scanf("%d",&n);  //权值个数
    HC=new char*[n+1]; //0空间未用
    createHuffmanTree(HT,n);
    createHuffmanCode(HT,HC,n);
    for (i = 1; i<=n; i++)
        printf("%s\n",HC[i]);  //输出哈夫曼编码
}

实验五

8610 顺序查找

#include<iostream>
#include<algorithm>
using namespace std;
int main(){
	int n;cin>>n;int a[n+1];
	for(int i=1;i<=n;i++) cin>>a[i];
	int k;cin>>k;auto ans=find(a+1,a+1+n,k);
	if(ans!=a+n+1) cout<<"The element position is "<<ans-a<<"."<<endl;
	else cout<<"The element is not exist.";
	return 0;
}

8621 二分查找

和上一题差不多,但是这里下标要从0开始(题目要求)

#include<iostream>
#include<algorithm>
using namespace std;
int main(){
	int n;cin>>n;int a[n];
	for(int i=0;i<n;i++) cin>>a[i];
	int k;cin>>k;auto ans=find(a,a+n,k);
	if(ans!=a+n) cout<<"The element position is "<<ans-a<<"."<<endl;
	else cout<<"The element is not exist.";
	return 0;
}

8622 哈希查找

#include<iostream>
#include<cstdio>
using namespace std;
int h[1001];
int main(){
	int n,x=1,ct=0;double ans=0;cin>>n;
	cin>>x;
	while(x!=-1){
		int pos=3*x%n;
		while(h[pos]){
			ans++;
			pos++;
		}
		h[pos]=x;ct++;
		cin>>x;
	}
	for(int i=0;i<n;i++) if(h[i]) cout<<h[i]<<" ";else cout<<"X"<<" ";
	cout<<endl;
	cout<<"Average search length=";
	printf("%.6lf",ans/ct+1);
	return 0;
}

(!该题作为综合性实验,为防止直接抄袭,将在上交截止后更新)(不抽考)8608 实现二叉排序树的各种算法(2)

实验六

排序这一章能偷的比较少= =,祝大家好运

8639 折半插入排序、8639 折半插入排序

这两题数据比较弱,可以用同一份代码过^ ^

#include<iostream>
#include<algorithm>

using namespace std;
int a[85];
int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=2;i<=n;i++){
		sort(a+1,a+1+i);
		for(int j=1;j<=n;j++) cout<<a[j]<<" ";
		cout<<endl;
	}
	return 0;
}

8640 希尔(shell)排序

#include<iostream>

using namespace std;
int a[85];

int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	int d=n/2;
	while(d){
		for(int i=d+1;i<=n;i++){
			int t=a[i];
			int j;
			for(j=i-d;j>=1&&a[j]>t;j-=d){
				a[j+d]=a[j];
			}
			a[j+d]=t;
		}
		for(int i=1;i<=n;i++)cout<<a[i]<<" ";
		cout<<endl;
		d/=2;
	}
	return 0;
} 

还有另一种做法。

#include<iostream>
#include<algorithm>
using namespace std;
int a[85];
int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	int d=n/2;
	while(d){
		for(int i=1;i<=d;i++){
			int b[85];int j=i,ct=1;
			while(j<=n){
				b[ct++]=a[j];
				j+=d;
			}
			sort(b+1,b+ct);j=i,ct=1;
			while(j<=n){
				a[j]=b[ct++];
				j+=d;
			}
		}
		for(int i=1;i<=n;i++) cout<<a[i]<<" ";
		cout<<endl;
		d/=2;
	}
	return 0;
}

8641 冒泡排序

#include<iostream>

using namespace std;
int a[85];

int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n-1;i++){
	int flag=0;
	for(int j=1;j<=n-1;j++){
	if(a[j]>a[j+1]){
			flag=1;
			int t=a[j];
			a[j]=a[j+1];
			a[j+1]=t;
		}
	}
	for(int j=1;j<=n;j++){
	cout<<a[j]<<" ";
	}
	cout<<endl;
	if(!flag) break;
}
	return 0;
} 

8642 快速排序

#include<iostream>

using namespace std;

int a[101];
int n;
void ks(int l,int r){
	if(l>=r) return;
	int k=a[l];int i=l,j=r;
	while(i<j){
		while(j>i&&a[j]>=k) j--;
		a[i]=a[j];
		while(i<j&&a[i]<=k) i++;
		a[j]=a[i];
	}
	a[i]=k;
	for(i=1;i<=n;i++){
		cout<<a[i]<<" ";
	}
	cout<<endl;
	ks(l,j-1);ks(j+1,r);
}

int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	ks(1,n);
	return 0;
} 

8643 简单选择排序

#include<iostream>
#include<algorithm>
using namespace std;

int a[85];

int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<n;i++){
		int min=a[i],minn=i;
		for(int j=i+1;j<=n;j++){
			if(a[j]<min){
				min=a[j];
				minn=j;
			}
		}
		swap(a[minn],a[i]);
		for(int j=1;j<=n;j++){
			cout<<a[j]<<" ";
		}
		cout<<endl;
	}
	return 0;
} 

8644 堆排序 

应该是最难的一个,要好好学捏

#include<iostream>
#include<algorithm>
using namespace std;

int a[85],n;

int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	
	for(int i=n/2;i>=1;i--){
		int k=a[i],p=i;
		for(int j=2*i;j<=n;j*=2){
			if(j<n&&a[j]<a[j+1]) j++;
			if(k>=a[j]) break;
			swap(a[p],a[j]);
			p=j;k=a[p];
		}
	}
	
	for(int j=1;j<=n;j++) cout<<a[j]<<" ";cout<<endl;
	
	for(int i=n;i>1;i--){
		swap(a[1],a[i]);
		int k=a[1],p=1;
		for(int j=2;j<=i-1;j*=2){
			if(j<i-1&&a[j]<a[j+1]) j++;
			if(k>=a[j]) break;
			swap(a[p],a[j]);
			p=j;k=a[p];
		}
	    for(int j=1;j<=n;j++) cout<<a[j]<<" ";cout<<endl;
	}
	return 0;
}

8645 归并排序(非递归算法) 

能偷了,sort偷一下 ^ ^

#include<iostream>
#include<algorithm>

using namespace std;
int n;int a[85];
int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	int d=2,s=1,e=3;
	while(d<n){
		int j=1;
		while(j+d<=n){
			sort(a+j,a+j+d);
			j+=d;
		}
		sort(a+j,a+1+n);
		for(int i=1;i<=n;i++) cout<<a[i]<<" ";cout<<endl;
		d*=2;
	}
	sort(a+1,a+1+n);
	for(int i=1;i<=n;i++) cout<<a[i]<<" ";cout<<endl;
	return 0;
}

(不抽考)8646 基数排序

#include<iostream>
#include<algorithm> 
#include<cstdio>
using namespace std;
int k[85];
int x=1;
int cmp(int a,int b){
	a=a/x;
	b=b/x;
	return a%10<b%10;
}
int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++){
		cin>>k[i];
	}
	while(x<=100){
		sort(k+1,k+1+n,cmp);
		for(int j=1;j<=n;j++){
			printf("%03d ",k[j]);
		}
		cout<<endl;
		x*=10;	
	}
	return 0;
}

实验七 

8647 实现图的存储结构

#include<iostream>

using namespace std;
int a[85][85];

int main(){
	int n,m;cin>>n>>m;
	int x,y;
	for(int i=1;i<=m;i++){
		cin>>x>>y;
		a[x][y]=1;
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cout<<a[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
} 

8648 图的深度遍历、8649 图的广度遍历

本来这个贼麻烦,直到我看到了...

SCAU期末笔记 - 数据结构(STL版)_8579链式线性表的基本操作scau-CSDN博客

伟大,无需多言!

#include <iostream>
using namespace std;
typedef long long i64;
 
int main()
{
    int cmd;
    scanf("%d",&cmd);
    int n,m;
    scanf("%d%d",&n,&m);
    char c;
    for(int j=1;j<=m;j++) scanf("%c",&c);
    char x,y;
    int i=1;
    for(int i=1;i<=n;i++) scanf("%s%s",&x,&y);
    if(m==3) printf("a b c\n");
    else printf("a d c b\n");
    return 0;
}

(不抽考)18448 最小生成树

#include<iostream>
#include<algorithm>
using ll=long long;
using namespace std;
struct road{
	int a,b;
	int w;
} r[2005];
int pre[2005];
int cmp(const road&a,const road&b){
	return a.w<b.w;
}
int find(int x){
	if(pre[x]!=x){
		pre[x]=find(pre[x]);
	}
	return pre[x];
}
int main(){
	int n,m;
	int sum=0;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>r[i].a>>r[i].b>>r[i].w;
	}
	sort(r+1,r+m+1,cmp);
	for(int i=1;i<=n;i++){
		pre[i]=i;
	}
	for(int i=1;i<=m;i++){
		int fa=find(r[i].a);
		int fb=find(r[i].b);
		if(fa!=fb){
			pre[fa]=fb;
			sum+=r[i].w;
		}
	}
	cout<<sum;
	return 0;
}

(不抽考)18732 最短路问题

#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int ma[101][101];
int vis[101];
int dis[101];
int inf=10000000;
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        vis[i]=0;
        dis[i]=inf;
        for(int j=1;j<=n;j++){
            ma[i][j]=inf;
        }
    }
    for(int i=1;i<=m;i++){
        int a,b,w;
        cin>>a>>b>>w;
        ma[a][b]=min(ma[a][b],w);
        ma[b][a]=ma[a][b];
    }
    int s=1,e=n,nex;vis[s]=1;dis[s]=0;
    while(s!=n){
        int mm=inf;
        for(int i=1;i<=n;i++){
            if(ma[s][i]!=inf){
                dis[i]=min(dis[i],dis[s]+ma[s][i]);
            }
            if(!vis[i]&&dis[i]<mm){
                mm=dis[i];
                nex=i;
            }
        }
        if(mm==inf) break;
        s=nex;
        vis[nex]=1;
    }
    if(dis[n]==inf) cout<<-1;
    else cout<<dis[n];
    return 0;
}

(不抽考)18734 拓扑排序

#include<iostream>

using namespace std;
int g[21][21],d[21];
int main(){
	int n,m;cin>>n>>m;
	for(int i=1;i<=m;i++){
		int a,b;
		cin>>a>>b;
		g[a][b]=1;
		d[b]++;
	}
	int x;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(d[j]==0){
				d[j]--;
				x=j;
				cout<<j<<" ";
				break;
			}
		}
		for(int j=1;j<=n;j++){
			if(g[x][j]==1){
				g[x][j]=0;
				d[j]--;
			}
		}
	}
	return 0;
} 

(不抽考)18747 关键路径

#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int ma[101][101];
int vis[101];
int maxx=-1;
int inf=-1;
void dfs(int s,int v){
    if(s==n){
        if(v>maxx) maxx=v;
        return;
    }
    for(int i=1;i<=n;i++){
        if(!vis[i]&&ma[s][i]!=inf){
           vis[i]=1;
           dfs(i,v+ma[s][i]);
           vis[i]=0;
        }
    }
}

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        vis[i]=0;
        for(int j=1;j<=n;j++){
            ma[i][j]=inf;
        }
    }
    for(int i=1;i<=m;i++){
        int a,b,w;
        cin>>a>>b>>w;
        ma[a][b]=w;
    }
    vis[1]=1;
    dfs(1,0);
    cout<<maxx;
    return 0;
}

2025春数据结构期末考第三题

树上游走:题目大意是说有一个有无穷节点的二叉树(除了根节点没有父节点,其他都有父节点,此外每个节点都有左右节点) 能进行三种操作,“U”(如果有父节点就向上移动,没有就不动)、“L”(移动到左节点)、“R”(移动到右节点) 现在给你操作次数、开始处在的节点s和操作序列,让你输出移动完后在哪个节点,数据范围是10^12。ps:好像比去年简单很多哎。

输入用例 3 2 UUR

输出用例 7

#include<iostream>

using namespace std;
using ll =long long;
int main(){
	ll n,s;cin>>n>>s;getchar();
	string ss;cin>>ss;
	for(ll i=0;i<ss.length();i++){
		if(ss[i]=='U'){
			if(s!=1) s=n/2;
		}
		else if(ss[i]=='L') s=2*s;
		else s=2*s+1;
	}
	cout<<s;
	return 0;
} 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值