当前位置: 首页 > news >正文

【数据结构】实验四:循环链表

实验四  循环链表

一、实验目的与要求

1)熟悉循环链表的类型定义和基本操作;

2灵活应用循环链表解决具体应用问题。

二、实验内容

题目一:有n个小孩围成一圈,给他们从1开始依次编号,从编号为1的小孩开始报数,数到第m个小孩出列,然后从出列的下一个小孩开始重新报数,数到第m个小孩又出列,……如此反复直到所有的小孩全部出列为止,求整个出列序列,例如:当n=6,m=5 时的出列序列是5,4,6,2,3,1 . 

题目二:围绕着山顶有10个洞,一只狐狸和一只兔子住在各自的洞里。狐狸想吃掉兔子。一天,兔子对狐狸说:“你想吃我有一个条件,先把洞从110编上号,你从10号洞出发,先到1号洞找我;第二次隔1个洞找我,第三次隔2个洞找我(第一次看1号洞,第二次看3号洞,第三次看6号洞),以后依次类推,次数不限,若能找到我,你就可以饱餐一顿。不过在没有找到我以前不能停下来。”狐狸满口答应,就开始找了。它从早到晚进了100次洞,也没找到兔子,请问,兔子可能躲在几号洞里,打印输出所有安全洞的编号。(使用一个循环单链表解决问题)

三、实验结果

1)请将调试通过的源代码粘贴在下面。(代码注意书写规范、主要模块要有功能注释)

题目一源代码:

#include <cstdio>
#include <malloc.h>
#include <iostream>
using namespace std;typedef struct node{int no;//小孩编号struct node *next;		
}child;//创建无头结点
void createlist(child *&head, int n){int i;child *p,*tail;//指向新建循环单链表的尾结点head=(child*)malloc(sizeof(child));head->no=1;//建立no为1结点的单链表tail=head;for(i=2;i<=n;i++){p=(child*)malloc(sizeof(child));p->no=i;//建立一个存放编号i的结点tail->next=p;tail=p;//将p结点链到末尾}tail->next=head;//构成一个首结点为head的循环单链表
}//求出列顺序(约瑟夫问题) 
void joseph(int n,int m){//n->总数 m->出列数 int i,j; child *head,*p,*q;createlist(head,n);//初始化列表 //出列n个小孩for(i=1;i<=n;i++){p=head; j=1;//从head结点开始报数,报到第m-1个结点while(j<m-1){j++;//报数递增p=p->next;//移到下一个结点}q=p->next;//q指向第m个结点cout<<q->no<<" ";//该结点出列p->next=q->next;free(q);//删除q结点(出列结点) head=p->next;//从下一个结点重新开始}
}int main(){int n,m;//n->总数 m->出列数cin>>n>>m;joseph(n,m);return 0;
}

题目一结果展示:

 

 题目二源代码:

#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;//创建结点 
typedef struct node{int a,b;//a为安全洞的标记,b为洞的序号struct node *next;
}node;//主函数->find safe holes
int main(){node *p,*q;p=(node*)malloc(sizeof(node));p->b=1;p->a=1;q=p;//记录头结点 int i=0;while(i<9){//创建十个结点 p->next=(node*)malloc(sizeof(node));p=p->next;//移动到下一个新结点 p->b=i+2;//洞的序号p->a=0;i++;}p->next=q;//构建循环 p=p->next;//回到头结点 //寻找安全洞并标记狐狸洞(进100次洞) for(i=0;i<100;i++){int j;int temp=(i+2)%10;//序号归类为1-10 for(j=0;j<temp;j++){p=p->next;}p->a=1;//标记狐狸洞 }//输出安全洞 for(i=0;i<10;i++){if(p->a==0){//非兔子洞已经进行标记 cout<<"可能在第"<<p->b<<"个洞里面"<<endl;}p=p->next;//遍历,移动到下一个结点 }return 0;
}

题目二结果展示:

 

2)请分析你程序中每个功能模块的算法时间复杂度。

题目一:

构建含有n个元素的循环链表。时间复杂度为O(n)

本段代码由两层循环构成。内层循环通过从head结点开始报数,报到第m-1个结点,此时寻找到第m个结点(利用第m-1个结点的后继结点)并删除。外层循环在每剔除一个结点后再一次进行遍历。时间复杂度为O(n²)

题目二:

构建含有n个元素的循环链表,a为安全洞的标记,b为洞的序号。时间复杂度为O(n)

本段代码由两层循环构成。内层循环通过题目所给的狐狸进洞的规律,对其所有进入过的洞进行标记(即a=1),便于后续锁定兔子安全洞的位置。外层循环为题目所给的狐狸进洞的总次数(即100次进洞寻找兔子),并继承上一次进洞的位置。时间复杂度为O(n²)

通过之前化简进洞的序号,本段代码利用遍历输出安全洞的位置,即通过从开始的结点中遍历,寻找a标记为0的结点序号并输出。时间复杂度为O(n)


 其他参考:

#include<iostream>
using namespace std;// 定义结构体 
struct CLNode  
{int num;CLNode *next;
};
// 初始化链表 
void Initlist(CLNode *&L){  //注意引用!!! L=new CLNode;L->next=L;
}
// 创建链表元素
void Creatlist(CLNode *&L,int n){CLNode *p=L;for(int i=1;i<=n;i++){CLNode *q=new CLNode;q->num=i;q->next=L;   //循环链表的指针指向 p->next=q;p=q;}
}
// 输出链表元素
void Outlist(CLNode *&L){CLNode *p=L;cout<<"输出小孩序号如下:"<<endl; while(p->next!=L){p=p->next;cout<<p->num<<" ";}cout<<endl; 
}
// 输出出列序列
void Output(CLNode *&L,int m){CLNode *p=L->next;CLNode *pre=L;//定义pre指针以便删除元素操作 for(int i=1;i<=m;){if(p->next==L){if(p->next->next==L)//循环结束条件 break;else{pre=pre->next->next;p=p->next->next;}}else{pre=pre->next;p=p->next;}i++;if(i==m){cout<<p->num<<" ";pre->next=p->next;CLNode *q=p;p=p->next;q->next=NULL;delete q;if(p!=L) //注意条件! i=1;elsei=0;  //注意避开头结点 }}
}
// 释放空间 
void Destroylist(CLNode *&L){delete L;//删除头结点 
}int main(){CLNode *L;       //定义头指针 Initlist(L);     //初始化链表 int n,m;cout<<"请输入小孩的总人数:"<<endl;cin>>n; Creatlist(L,n);  //插入链表元素 Outlist(L);      //输出链表元素 cout<<"请输出出列序号:"<<endl;cin>>m;cout<<"当n="<<n<<",m="<<m<<"时的出列序号为:"<<endl;Output(L,m);    //根据序号输出依次链表元素 Destroylist(L);//释放空间 
}
#include<iostream>
using namespace std;
// 定义结构体
struct CLNode  
{int num;CLNode *next;
};
// 初始化链表
void Initlist(CLNode *&L){  //注意引用!!! L=new CLNode;L->next=L;
}
// 创建链表元素
void Creatlist(CLNode *&L,int n){CLNode *p=L;for(int i=1;i<=n;i++){CLNode *q=new CLNode;q->num=i;q->next=L;   //循环链表的指针指向 p->next=q;p=q;}
}
// 输出链表元素 
void Outlist(CLNode *&L){CLNode *p=L;cout<<"输出山洞序号如下:"<<endl; while(p->next!=L){p=p->next;cout<<p->num<<" ";}cout<<endl; 
}
// 寻找安全洞 
void Safenum(CLNode *&L){cout<<"安全洞的编号可能为:"<<endl;CLNode *p=L;int a[101];    //储存被循环到的链表元素 int i=1;while(i<=100){   //使循环次数足够多 for(int j=0;j<i;j++){if(p->next==L)p=p->next->next;elsep=p->next;}a[i-1]=p->num;i++;}for(int j=1;j<=10;j++){for(i=0;i<100;i++){if(a[i]==j)break;} if(i>=100)cout<<j<<" ";}
}
// 释放空间
void Destroylist(CLNode *&L){CLNode *p=L->next;while(p!=L){ //除了头结点的所有结点 CLNode *q=p;p=p->next;q->next=NULL;delete q;}delete p;//删除头结点 
}int main(){CLNode *L;       //定义头指针 Initlist(L);     //初始化链表 Creatlist(L,10);  //插入链表元素 Outlist(L);      //输出链表元素 Safenum(L);    //找到安全洞 Destroylist(L);//释放空间 
}

http://www.lryc.cn/news/97632.html

相关文章:

  • 【FPGA/D7】
  • Vue的下载以及MVVM分析
  • ElasticSearch学习--自动补全
  • 【C++】多态,虚函数表相关问题解决
  • 探索大型语言模型的开源人工智能基础设施:北京开源AI Meetup回顾
  • Langchain 的 Conversation buffer window memory
  • 电流源电路
  • iOS开发-CMMotionManager传感器陀螺仪
  • 影刀下载,插件安装
  • Linux的tcpdump命令详解
  • springboot运行报错Failed to load ApplicationContext for xxx
  • [SQL挖掘机] - 内连接: inner join
  • mysql(四)数据备份
  • Spring 拦截器
  • 【libevent】http客户端3:简单封装
  • JavaScript的函数中this的指向
  • Caddy 中实现自动 HTTPS
  • SK5代理(socks5代理)在网络安全与爬虫应用中的优势与编写指南
  • 【LeetCode-简单】剑指 Offer 06. 从尾到头打印链表(详解)
  • 【LeetCode】114.二叉树展开为链表
  • DAY3,Qt(完成闹钟的实现,定时器事件处理函数的使用)
  • TL-ER3220G设置vlan
  • PHPWord 实现合并多个word文件
  • rust持续学习Box::leak
  • 通过SSH实现将本地端口反向代理到公网服务器
  • Fragment的基本用法、Fragment和活动间的通信、Fragment的生命周期、动态加载布局的技巧
  • 机器学习 day30(正则化参数λ对模型的影响)
  • 图文教程:如何在 3DS Max 中创建3D迷你卡通房屋
  • 根据UIL下载图片/视频、根据URL自动下载图片/视频、GUI自动下载想要的图片
  • HTML <picture> 标签