数据结构实验第二周



这题就套公式即可

6-1 结构体查找
简单的遍历,但是注意字符串的存放,要在末尾处添加'\0',否则就会过不了

int find(RECORD a[], int n,RECORD b[]){

    int p=0,sum=0;
    int swj=0;
    for(int i=0;i<n;i++)
    {
        if(a[i].score>=60 && a[i].score<=79){
            b[p].score=a[i].score;
            sum++;
            //swj swj swj 
            int j;
            for( j=0;a[i].no[j]!='\0';j++) b[p].no[j]=a[i].no[j];
            b[p].no[j]='\0';
            p++;
        }
    }
    
	return sum;
//swj
}

6-2 顺序表实现

这种出题的是真的无敌,一大堆摆在那干扰你的阅读

  • 第一个函数直接返回长度即可
  • 第二个函数注意下标是从0开始,返回的是i+1
  • 第三个函数,注意插入的位置题目要求的是1-i个位置,但是我们存放的下标是从0开始。插入的原理:在某个位置之前插入就是把这个位置和这个位置以后的所有元素往后挪一位,然后最后这个空出来的位置赋值为插入值即可。但是注意插入的位置不可以小于1或者大于L.length+1,L.length+1就是插在这个顺序表的末尾,再往后就是不符合情况的了,并且再插入完以后,注意更新顺序表的长度和存储容量
int ListLength(SqList L) 
//返回顺序线性表长度;
{
	return L.length;
}

int LocateElem(SqList L,ElemType e,Status(*compare)(ElemType,ElemType))
//返回L中第1个与e满足关系compare()的数据元素的位序。 若这样的数据元素不存在,则返回值为0。
{
	for(int i=0;i<L.length;i++)
	{
		int  k=L.elem[i];
		if(compare(k,e)){
			return i+1;
		}
	}
	 return 0;
	
}


Status ListInsert(SqList &L,int i,ElemType e) 
//在L中第i个位置之前插入新的数据元素e,L的长度加1,并返回OK,若i不合法,则返回ERROR,注意可能空间会已满,则L需要申请更大的存储空间;
{
	if(i<1||i>L.length+1) return ERROR;
    
	for(int j=L.length;j>=i;j--)
	{
		*(L.elem+j)=*(L.elem+j-1);
	}
	L.elem[i-1]=e; //注意我这是i-1,
    L.length++; //插入后更新长度
    
    if(L.listsize<L.length) L.listsize=L.length+1; //注意这里没写 全部0分
	return OK;
  int swj=0;
}

6-3 带头单链表实现

不懂链表的知识可以去b站看,或者看我文章数据结构
原理其实和数组是差不多的,只是我们遍历的时候,使用地址来找下一个结点,而数组是顺序存储的所以可以直接找下一个。

int ListLength(LinkList L)   
{
	LNode *p; //定义一个链表型的指针
	int ans=0;
	p=L->next; //指针指向头结点下的第一个元素
	while(p!=NULL){//求长度,当遍历到NULL时说明遍历完了
		p=p->next;
		ans++;
	}
	
	return ans;
int swj=0;
}

int LocateElem(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType))
{
	LNode *p;
	p=L->next;
	int j=0;
	while(p!=NULL)
	{
		if( compare(p->data,e) ) {
			return j+1;//同理下标是从0开始的
		}
		p=p->next;
		j++;
	}
	return 0;
}

Status ListInsert(LinkList &L,int i,ElemType e) 
//在L中第i个位置之前插入新的数据元素e,并返回OK,若i不合法,则返回ERROR;
{
	int len=ListLength(L);
	LNode *s;
	s=(LNode*)malloc(sizeof(LNode));//申请内存来存结点
	if(i>len+1||i<1) return ERROR;//这里是大于len+1而不是len
	int j=i-1;//遍历到第i个结点的前一个结点,让这个结点指向当前结点的下一个结点,
//当前结点再指向插入结点,也就是头插法
	LNode *p=L;
	while(j--&&p!=NULL)
	{
		p=p->next;
	}
//头插法,可以自己画图模拟一下
	s->data=e;
	s->next=p->next;
	p->next=s;
	return OK;
	
	
	int swj=0;
}

7-1 找最贵的书和最便宜的书

注意输入完数字以后,会有一个回车,每次输入一组数据的时候都要去吃掉回车,使用getline来输入含有空格的字符串,然后简单的结构体排序一下即可

#include <bits/stdc++.h>
using namespace std;
struct node{
	string s;
	double k;
};

int main()
{
	int n;
	cin>>n;
	vector<node>ve(n);
	for(int i=0;i<n;i++)
	{
		cin.ignore();//用来吃掉空格
		getline(cin,ve[i].s);//输入有空格的字符串
		cin>>ve[i].k;
	}
	
	sort(ve.begin(),ve.end(),[](node x,node y){
		return x.k>y.k;
	});//可以自己写个void cmp(node x, node y)
	
	cout<<fixed<<setprecision(2)<<ve[0].k<<", "<<ve[0].s;
	cout<<endl; //swj 水印
	cout<<fixed<<setprecision(2)<<ve[n-1].k<<", "<<ve[n-1].s;
	
	int swj=0;
	
}

7-2 重排链表

先对链表进行后半段的翻转,翻转完以后交替输出,或者像我一样直接排成题目要求的结构,但是我这样会比较麻烦。
用数组来模拟链表,开一个结构体,存值和地址,遍历的时候注意我写的for和while
记得讨论奇偶的情况
并且有一种情况是会有多余没用的结点,就是导数第二个测试点

#include <bits/stdc++.h>
using namespace std;
 struct node{
	int data;
	int next;
}ve[100005];


int main()
{
	int head,n;
	cin>>head>>n;
	for(int i=0;i<n;i++)
	{
		int x,y,z;
		cin>>x>>y>>z;
		ve[x].data=y;
		ve[x].next=z;
	}
	n=0;
	for(int i=head;i!=-1;i=ve[i].next)
	{
		n++;
	}
	


    //先找到n/2个结点,向下取整的n/2
	int pre=-1,cnt=1,mid=-1;
	for(int i=head;i!=-1;i=ve[i].next)
	{
		if(cnt==n/2) {
			mid=i;//i是当前结点的地址
			break;
		}
		cnt++;
	}
	

    //从中间结点的下一个结点开始翻转
	int p=ve[mid].next;
	ve[mid].next=-1;
//	cout<<ve[p].data<<" "<<ve[mid].next;
	int tmp;
	for(int i=p;i!=-1;i=tmp)
	{
	    //头插法翻转
		 tmp=ve[i].next;
		ve[i].next=ve[mid].next;
		ve[mid].next=i;
			
	}
	
	int h=head;

	head=ve[mid].next;
	//翻转完以后

//	}
	
//把链表连接成题目要求的形式
	int r=head;
	mid=r;
//	cout<<mid<<endl; //swjswjswj
	int	ta,tb;
	while(r!=-1&&h!=-1)
	{
	
		ta=ve[h].next;
		tb=ve[r].next;
	
		ve[h].next=ve[r].next;	
		ve[r].next=h;
		
		r=tb;
		h=ta;
		if(ta==mid) break; //处理奇数的情况
	
		
	}
	
	
	for(int i=head;i!=-1;i=ve[i].next){
		if(i!=-1){
		if(i<10&&i!=-1) cout<<"0000";
		else if(i<100) cout<<"000";
		else if(i<1000) cout<<"00";
		else if(i<10000) cout<<"0";
		}
		cout<<i<<" "<<ve[i].data<<" ";
	
		if(ve[i].next!=-1){
		if(ve[i].next<10) cout<<"0000";
		else if(ve[i].next<100) cout<<"000";
		else if(ve[i].next<1000) cout<<"00";
		else if(ve[i].next<10000) cout<<"0";
		}
		cout<<ve[i].next<<endl;
	}
	int swj=0;
}

7-3 运用循环单链表实现约瑟夫问题

把每个数组的下标当成当前元素值,然后数组里存它的下一个位置即可,也就是模拟链表,对于b的倍数标记一下,然后只遍历没标记过的即可

#include <bits/stdc++.h>
using namespace std;


int main()
{
	 int n,b;
	cin>>n>>b;
	int id[1005]={0};
	for(int i=1;i<n;i++)
	{
		id[i]=i+1;
	}
	id[n]=1;
	int head=1;
	int cnt=0;
	map<int,bool>mp;
	int sum=0;
	for(int i=head;sum<n-2;i=id[i]){
		if(!mp[i] )
		{
			cnt++;
			if(cnt%b==0) mp[i]=1,sum++;
		}
	}

//	cout<<cnt<<endl;
//	for(auto [x,y] :mp) cout<<x<<" "<<y<<endl;
	vector<int>ans;
	for(int i=head;id[i]!=head;i=id[i])
	{
		if(!mp[i]) ans.push_back(i);
	}
	
	if(ans[0]>ans[1]) swap(ans[0],ans[1]);
	cout<<ans[0]<<" "<<ans[1];
}

posted on 2024-09-22 20:19  swj2529411658  阅读(8)  评论(0编辑  收藏  举报

导航