链表解
思路简单,但需要很多函数辅助
#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
int val;
struct Node* next;
}Node;
void searchlist(Node *p);
Node* addbyNode(Node *p,int val);
Node* delcirbyNode(Node* list,Node *p);
Node* joseph(Node *head,int n,int k,int m){
//一共n个节点,第k个位置开始,报到第m个淘汰
Node *p=head;
for(int i=0;i<k-1;i++){
//i=k-1时无法进入循环,往后跳了k-1次
p=p->next;
}
// Node* r=p;
while(p->next!=p){
//一直删除直到只剩一个节点
for(int i=0;i<m-1;i++){
//r=p;
p=p->next;
}
Node *r=p;
p=p->next;//下一轮开始位置
//节点删除前记录下接下来的路径
head=delcirbyNode(head,r);
}
return head;
}
int main(){
int n;
scanf("%d",&n);
Node *head=NULL;
Node *tail=NULL;
for(int i=0;i<n;i++){
int val;
scanf("%d",&val);
if(head==NULL){
head=addbyNode(head,val);
tail=head;
}else{
tail=addbyNode(tail,val);
}
}
tail->next=head;
searchlist(head);
head=joseph(head,n,2,1);//删除操作一定要返回新节点
searchlist(head);
return 0;
}
void searchlist(Node *list){
Node *p=list;
do{
printf("%d\n",p->val);
p=p->next;
}while(p!=list);
return;
}
Node* addbyNode(Node *p,int val){
if(p==NULL){
Node* p=(Node *)malloc(sizeof(Node));
p->val=val;
p->next=NULL;
return p;
}
Node* newNode=(Node *)malloc(sizeof(Node));
newNode->val=val;
newNode->next=p->next;
p->next=newNode;
return newNode;
}
Node* delcirbyNode(Node* list,Node *p){
//遍历找到要删除的节点后调用
if(p==list){
Node *q=list;
while(q!=NULL&&q->next!=p){
q=q->next;
}
q->next=p->next;
list=p->next;
free(p);
return list;
}else{
Node *q=list;
while(q!=NULL&&q->next!=p){
q=q->next;
}
q->next=p->next;
free(p);
}
return list;
}
数组解
数组解,代码简单
#include<stdio.h>
int arr[100];
int mark[100];
int CircleAdd(int i,int n){
//模拟环形链表和节点删除
if(i==n){
i=1;
}else{
i+=1;
}
//判断当前位置是否合法
while(mark[i]!=0){
i=CircleAdd(i,n);
}
return i;
}
void josephuArr(int n,int k,int m){
int i=k;
while(i!=CircleAdd(i,n)){
//往后面跳m-1次
for(int cn=0;cn<m-1;cn++){
i=CircleAdd(i,n);
}
mark[i]=1;
i=CircleAdd(i,n);
}
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&arr[i]);
}
josephuArr(n,2,1);
for(int i=1;i<=n;i++){
if(mark[i]==0){
printf("%d",arr[i]);
}
}
return 0;
}