【数据结构】第四周

单链表、栈、队列(创建、添加、删除、合并、查找等操作)

1.约瑟夫环问题

【问题描述】用不带头结点的单向循环链表解决约瑟夫环问题。

【输入形式】输入n和m的值,其中n为总人数,m为报数的密码

【输出形式】胜利者编号,也就是最后一个离开队伍的人

【样例输入】6 4

【样例输出】5

约瑟夫环问题_小C哈哈哈的博客-CSDN博客

#include<bits/stdc++.h>
using namespace std;
//用数组实现约瑟夫环问题
int a[110]={0};   //元素值为0表示未出局 
//i既代表数组的下标,也代表每个人的编号
//k是用来计数的,一旦k的值达到m,代表此人需要出局,并且k需要重新计数,这样才能够找出所有需要出局的人
//数组的0代表未出局的人,数组非0代表出局的人,未出局的人需要报数,出局的人不需要报数 
int main()
{
	int N,M;
	int cnt=0,i=0,k=0;  //cnt表示目前出局的人数 
	cin>>N>>M;  //表示总共有n人,数到数字m时出局 
	while(cnt!=N) //因为要求N个人的出局顺序,因此当cnt(用来统计已经出局的人)未达到n时,需要循环不断报数 
	{
		i++;   //i是每个人的编号 
		if(i>N) i=1;  //这里需要特别注意:i的值是不断累加的,一旦发现i的值>N,那么i需要重新从第1个人开始
		              //数组要从第一个元素重新开始一个一个往后判断 
		if(a[i]==0)   //只有元素值为0的人 才需要报数,元素值为非0的代表已经出局了,不用报数 
		{
			k++;
			if(k==M)     //代表已经某个人已经报了M这个数,需要出局 
			{
				a[i]=1;  //编号为i的这个人出局 
				cnt++;   //出局的人数+1 
				cout<<i<<" ";  //输出出局的人的编号 
				k=0;   //清空k,让下一个人重新从1开始报数   
			}
		}
	}
	return 0;
} 
2.单链表的变换

【问题描述】设线性表L={a1,a2,a3,...,an-2,an-1,an}采用带头结点的单链表保存,请设计一个空间复杂度为O(1)且时间上尽可能高效的算法,重新排列L中的各结点,得到线性表L'={a1,an,a2,an-1,a3,an-2,...)。【2019统考真题】

【样例输入1】1 2 3 4 5 0

【样例输出1】1 5 2 4 3

【样例输入2】1 2 3 4 5 6 0

【样例输出2】1 6 2 5 3 4

【提示】0代表输入结束

【问题描述】设线性表L={a1,a2,a3,...,an-2,an-1,an}(带头结点),请设计空间复杂度为O(1)算法,重新排列L,得到L‘={a1,an,a2,an-1,a3,an-2,...)_Daylightap的博客-CSDN博客

#include<iostream>
#include<malloc.h>
#include<stdlib.h>
using namespace std;
typedef struct LinkNode{
	int data;
	struct LinkNode *next;
}LinkNode,*pList;

int build(pList &L)
{
	int x;
	L=new LinkNode;
	L->next=NULL;
	pList tail,newp;
	tail=L;
	cin>>x;
	int cnt=0;
	while(x!=0)
	{
		newp=new LinkNode;
		newp->data=x;
		newp->next=NULL;
		tail->next=newp;
		tail=newp;
		cnt++;
		cin>>x;
	}
	return cnt;
}
void travel(pList head)
{
	pList p;
	p=head->next;
	while(p)
	{
		cout<<p->data<<" ";
		p=p->next; 
	}
}

int main()
{
	pList head,tail,slow,fast;
	int n=build(head);
//		travel(head);
	slow=head->next;
	fast=head->next;

	while((fast->next->next&&n%2==0)&&(fast->next!=NULL&&n%2!=0))
	{
		slow=slow->next;
		fast=fast->next->next;
	}
	if(n%2==0)
	{
	while(fast->next->next)
	{
		slow=slow->next;
		fast=fast->next->next;
	}
	}else{
	while(fast->next!=NULL)
	{
		slow=slow->next;
		fast=fast->next->next;
	}
	}
	cout<<n<<endl;
	travel(head);
	printf("\n中间的点:%d\n",slow->data);

	
	pList latter=slow->next,cur=latter,follow;
	slow->next=NULL;
	
	while(cur){
		follow=cur->next;
		cur->next=slow->next;
		slow->next=cur;
		cur=follow;
	}
	//倒置后需要latter为最后一个指针,需要
	latter=slow->next;
	slow->next=NULL;
	
	cur=head->next;
	follow=latter;
	pList tmp=latter->next;
	while(cur&&follow) 
	{
		follow->next=cur->next;
		cur->next=follow;
		cur=cur->next->next;
		follow=tmp;
		if(tmp) tmp=tmp->next;
	}
	travel(head);
}

3.双向循环链表排序

【问题描述】实现不带头结点的双向循环链表的创建,然后实现该双向循环链表上数据的排序。(方法自定)
【输入形式】随机的数据
【输出形式】排序后的数据
【样例输入】5 7 2 8 1 3 4 9 6 0
【样例输出】1 2 3 4 5 6 7 8 9

【提示】0代表数据输入的结束

C语言实现双向非循环链表(带头结点尾结点)的基本操作_乞力马扎罗的雪CYF的博客-CSDN博客

这里引入另一篇专门写排序的文章

【数据结构】第十五周-排序_J娇娇_的博客-CSDN博客

#include <iostream>
 
using namespace std;
typedef struct Node
{
    int data;
    Node*prior,*next;
 
 
}Node,*LinkList;
void createlist(Node *head)//双向循环链表的创建
{ 
    Node*a=head;
   int num;
    Node*s;
 
  while (cin>>num)
  {
      if(num==0)
        break;
      else
      {
          s= new Node;
          s->data=num;
          a->next=s;
          s->prior=a;
          s->next=head;
          head->prior=s;
          a=s;
      }
  }
}
void Sort(Node *head)//插入排序
{   Node *L=head;
    Node*p,*q,*r;
 
    p=L->next;q=p->next;r=q->next;
    while(q!=L)
    {
        while((p!=L)&&(p->data>q->data))
                p=p->prior;
        q->prior->next=r;
        r->prior=q->prior;
        q->next=p->next;
        q->prior=p;
        p->next->prior=q;
        p->next=q;
        q=r;
        p=q->prior;
        r=r->next;
    }
}
void print(Node *head)
{ Node*L=head->next;
    while (L!=head)
    {
        cout<<L->data<<" ";
        L=L->next;
    }
 
}
int main()
{  Node * head=new Node;
   head->next=head;
   head->prior=head;
   createlist(head);
   Sort(head);
   print(head);
 
    return 0;
}

4.学生信息管理(综合项目题)

本题为小组综合项目题,请组长协调为各位组员分配任务,然后周末小组碰头集体讨论共同完成,提交相同的一份代码,每人在完成的模块后面写上注释。

【问题描述】设有一个存储学生信息的结构体包含:学号(no),姓名(name  ),班级号(classno),大学入学成绩总分(score),学生号指针(pno),班级号指针(pclass),成绩数指针(pscore)。请采用链式结构将信息读取并记录,并且完成如下功能:

1.添加一个学生记录

2.按学号no递增输出

3.按班级号classno递增输出,当classno一致时,按no递增顺序输出

4.按总分score递增输出,当score一致时,按no递增顺序输出

5.按学号删除:输入一个学号,删除该学号的学生记录,若无,则不执行

6. 修改某一学号学生的成绩:输入一个学号和成绩总分,找到该学号学生,修改成绩总分

7. 修改某一学号学生的姓名:输入一个学号和姓名,找到该学号学生,修改其姓名

8. 查找:输入一个成绩,查找该成绩总分的所有学生信息,按3的规则输出

9. 查找:输入一个班级号,查找该班级号所有学生信息,按4的规则输出

10.退出:退出运行程序

【提示】请用switch菜单模式完成

【目的】链表综合应用

【输入形式】一个整数代表操作类型,若需要则在下一行输入相关信息

【输出形式】按要求输出执行结果

【样例输入】

1

06208 gaoya 2103 630  

1  

06209 lisi 2104 617 

1

06210 lisi 2103 643

6                  

06208 600

4

10

【样例输出】

06209 lisi 2104 617

06208 gaoya 2103 630  

06210 lisi 2103 643  

06208 gaoya 2103 600 

06209 lisi 2104 617

06210 lisi 2103 643 

【样例说明】添加各学生记录之后,建立链表,执行各种操作。

30.0

C语言课程设计——学生信息管理系统_c语言课程设计学生信息管理系统_Lieb_Mark的博客-CSDN博客

#include <bits/stdc++.h>
 
using namespace std;
typedef struct stu
{
    int no;
   string name;
   int classno;
   float score;
    stu *pno;
   stu *pclass;
   stu *pscore;
   stu *p;
 
}stu;
stu *head;
void headlist(int no, string name, int classno, int score){
	stu* s = new stu;
	s->p = head->p;
	head->p = s;
	s->pno = head->pno;
	head->pno = s;
	s->pclass = head->pclass;
	head->pclass = s;
	s->pscore = head->pscore;
	head->pscore = s;
	s->classno = classno;
	s->name = name;
	s->no = no;
	s->score = score;
	return;
}
void Sort_no(stu* head){
	stu*pre,*cur,*next,*End;
	End= NULL;
	while(head->pno != End ){
		for(pre = head , cur = pre->pno, next = cur->pno; next != End; pre = pre->pno , cur = cur->pno , next =  next->pno){
			if(cur->no > next ->no ){
				pre->pno = next;
				cur->pno = next->pno;
				next->pno=cur;
				stu* s = cur;
				cur = next;
				next = s;
			}
		}
		End = cur;
	}
}
 
void Sort_classno(stu* head){
	stu*pre,*cur,*next,*End;
	End = NULL;
	while(head->pclass != End ){
		for(pre = head , cur = pre->pclass, next = cur->pclass; next != End; pre = pre->pclass , cur = cur->pclass , next =  next->pclass){
			if(cur->classno > next ->classno || (cur->classno == next->classno && cur->score > next->score) ){
				pre->pclass = next;
				cur->pclass = next->pclass;
				next->pclass=cur;
				stu*s = cur;
				cur = next;
				next = s;
			}
		}
		End = cur;
	}
}
void Sort_score(stu* head){
	stu *pre,*cur,*next,*End;
	End = NULL;
	while(head->pscore != End ){
		for(pre = head , cur = pre->pscore, next = cur->pscore; next != End; pre = pre->pscore , cur = cur->pscore , next =  next->pscore){
			if(cur->score > next ->score || (cur->score == next->score && cur->no > next->no) ){
				pre->pscore = next;
				cur->pscore = next->pscore;
				next->pscore=cur;
				stu* s = cur;
				cur = next;
				next =s;
			}
		}
		End = cur;
	}
}
void print_all(stu* head){
	stu* s= head->p;
	while(s!=NULL){
		cout << "0" << s->no << " " << s->name << " " << s->classno << " " << s->score << endl;
		s = s->p;
	}
}
void print_no(stu* head){
	stu* s= head->pno;
	while(s!=NULL){
		cout << "0" << s->no << " " << s->name << " " << s->classno << " " << s->score << endl;
		s= s->pno;
	}
}
void print_classno(stu* head){
	stu* s= head->pclass;
	while(s!=NULL){
		cout << "0" << s->no << " " << s->name << " " << s->classno << " " << s->score << endl;
		s = s->pclass;
	}
}
void print_score(stu* head){
	stu*s= head->pscore;
	while(s!=NULL){
		cout << "0" << s->no << " " << s->name << " " << s->classno << " " << s->score << endl;
		s = s->pscore;
	}
}
 
void clear_head(stu* head){
	stu* s= s->p;
	while(s!= NULL){
		stu* r = s;
		s= s->p;
		delete r;
	}
}
int main()
{
   head = new stu;
	head->p = NULL;
	head->pno = NULL;
	head->pclass = NULL;
	head->pscore = NULL;
	int Input;
	while(cin >> Input){
		if(Input == 1 || Input == 10 ) cout<<"select:"<<endl;
		if(Input == 1){
			int no, classno, score;
			string name;
			cin >> no >> name >> classno >> score;
    headlist(no, name, classno, score);
		}
		else if(Input == 2){
			print_all(head);
		}
		else if(Input == 3){
			Sort_no(head);
		}
		else if(Input == 4){
			Sort_no(head);
			print_no(head);
		}
		else if(Input == 5){
			Sort_classno(head);
		}
		else if(Input == 6){
			Sort_classno(head);
			print_classno(head);
		}
		else if(Input == 7){
			Sort_score(head);
		}
		else if(Input == 8){
			Sort_score(head);
			print_score(head);
		}
		else if(Input == 9){
			clear_head(head);
		}
		else if(Input == 10){
			break;
		}
 
 
}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值