joseph(约瑟夫)问题
1.设编号分别为:1,2, ...,n的n个人围坐一圈。
2.约定序号为k (1≤k≤n)的人从1开始计数,数到m的那个人出列,
3.他的下一位又从1开始计数,数到m的那个人又出列,依次类推,直到所有人出列为止。
例如,8个人围坐一圈,约定从第3个人开始编号为1,数到第4个人出列。出列后原来第5个人计算为1.n=8,k=3,m=4,最终出队的结果是62743518
提示:单向循环链表,删除头结点
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
int data;
struct node* next;
}Node, *pNode;
//初始化节点
void chu(pNode * head)
{
*head = (pNode)malloc(sizeof(Node));
if(NULL == *head)
{
printf("创建失败!!!\n");
return;
}
(*head)->next = *head;
return;
}
//尾插
void WeiInsert(pNode head, int data)
{
pNode new = (pNode)malloc(sizeof(Node));
if(NULL == new)
{
printf("新节点创建失败!!!\n");
return;
}
new->data = data;
pNode list = head;
while(list->next != head)
{
list = list->next;
}
new->next = head;
list->next = new;
return;
}
//按位置查找节点,并返回该节点的前一个节点
pNode find(pNode head, int m)//head是当前位置的地址
{
if(head == head->next)
{
printf("链表为空!!!\n");
return NULL;
}
pNode list = head;
for(int i = m-1; i > 1; i--)//查找需要取出的前一个节点
{
list = list->next;
}
return list;
}
//遍历
void bianli(pNode head)
{
pNode list = head;
while(list->next != head)
{
printf("%d ", list->next->data);
list = list->next;
}
return;
}
int main(int argc, char const *argv[])
{
int n = 0, k = 0, m = 0;
printf("请输入总人数,几号位为1,多少位出队:");
scanf("%d %d %d", &n, &k, &m);
pNode head = NULL;
chu(&head);
for(int i = 1; i <= n; i++)//创建链表
{
WeiInsert(head, i);
}
pNode end = head;
while(end->next != head)//查找最后一个节点
{
end = end->next;
}
pNode list = head->next;//头指针
end->next = head->next;//去除头结点
head->next = head;
pNode beg = list;//记录开始地址
pNode clean = NULL;//记录删除节点的前一个节点
pNode cl = NULL;//记录删除的节点
for(int i = 1; i < k; i++)//偏移到开始的位置
{
beg = beg->next;
}
for(int i = 1; i < n; i++)
{
clean = find(beg, m);
int data = clean->next->data;
WeiInsert(head, data);
beg = clean->next->next;
cl = clean->next;
clean->next = clean->next->next;
free(cl);
}
WeiInsert(head, beg->data);
free(beg);
bianli(head);
printf("\n");
return 0;
}
单向循环链表
头文件
#ifndef __TEST_H__
#define __TEST_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef int nodetype;
typedef struct node
{
nodetype data;
struct node* next;
}Node, *pNode;
void show();
void chuHead(pNode *head);
int lbcd(pNode head);
void HeadInsert(pNode head, nodetype data);
void weiInsert(pNode head, nodetype data);
void HeadClean(pNode head);
void LowClean(pNode head);
void bianli(pNode head);
#endif
主函数
#include "test.h"
int main(int argc, char const *argv[])
{
Node *head = NULL;
chuHead(&head);
nodetype data=0;
int s = 0;//存储选择的选项
while(1)
{
show();
printf("请输入选择:");
scanf("%d", &s);
switch (s)
{
case 1:
printf("请输入插入的数据:");
scanf("%d", &data);
//HeadInsert(head, data);
weiInsert(head, data);
break;
case 2:
//HeadClean(head);
LowClean(head);
break;
case 3:
bianli(head);
break;
case 0:
return 0;
default:
printf("输入有误,请重新输入!!!\n");
break;
}
}
return 0;
}
功能函数
#include "test.h"
void show()
{
printf("********1、插入数据********\n");
printf("********2、删除数据********\n");
printf("********3、打印数据********\n");
printf("********0、退出 ********\n");
return ;
}
//创建头结点
void chuHead(pNode *head)
{
*head = (Node*)malloc(sizeof(Node));
if(NULL == *head)
{
printf("创建失败!!!\n");
return ;
}
(*head)->next = *head;
return ;
}
//头插
void HeadInsert(pNode head, nodetype data)
{
pNode new = (pNode)malloc(sizeof(Node));
new->data = data;
new->next = head->next;
head->next = new;
return ;
}
//尾插
void weiInsert(pNode head, nodetype data)
{
pNode new = (pNode)malloc(sizeof(Node));
new->data = data;
pNode list = head;
while(list->next != head)
{
list = list->next;
}
new->next = list->next;
list->next = new;
return;
}
//头删
void HeadClean(pNode head)
{
if(head->next == head)
{
printf("链表为空!!!\n");
return;
}
pNode clean = head->next;
head->next = head->next->next;
clean->next = NULL;
free(clean);
return;
}
//尾删
void LowClean(pNode head)
{
if(head->next == head)
{
printf("链表为空!!!\n");
return;
}
pNode list = head;
while(list->next->next != head)
{
list = list->next;
}
pNode clean = list->next;
list->next = clean->next;
clean->next = NULL;
free(clean);
return;
}
//遍历
void bianli(pNode head)
{
if(head->next == head)
{
printf("链表为空!!!\n");
return ;
}
pNode list = head->next;
while(list != head)
{
printf("%d ", list->data);
list = list->next;
}
printf("\n");
return;
}
双向链表
头文件
#ifndef __TEST_H__
#define __TEST_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef int nodetype;
typedef struct node
{
nodetype data;
struct node* next;
struct node* perv;
}Node, *pNode;
void show();
void chuHead(pNode *head);
void sxHead(pNode *sxhead);
void HeadInsert(pNode head, nodetype data);
void weiInsert(pNode head, nodetype data);
void PlaceInsert(pNode head, nodetype data);
void HeadClean(pNode head);
void WeiClean(pNode head);
void PlaceClean(pNode head);
void bianli(pNode head);
#endif
主函数
#include "test.h"
int main(int argc, char const *argv[])
{
Node *head = NULL;
chuHead(&head);
nodetype data=0;
int s = 0;//存储选择的选项
while(1)
{
show();
printf("请输入选择:");
scanf("%d", &s);
switch (s)
{
case 1:
printf("请输入插入的数据:");
scanf("%d", &data);
//HeadInsert(head, data);
//weiInsert(head, data);
PlaceInsert(head, data);
break;
case 2:
//HeadClean(head);
//WeiClean(head);
PlaceClean(head);
break;
case 3:
bianli(head);
break;
case 0:
return 0;
default:
printf("输入有误,请重新输入!!!\n");
break;
}
}
return 0;
}
功能函数
#include "test.h"
void show()
{
printf("********1、插入数据********\n");
printf("********2、删除数据********\n");
printf("********3、打印数据********\n");
printf("********0、退出 ********\n");
return ;
}
//创建头结点
void chuHead(pNode *head)
{
*head = (Node*)malloc(sizeof(Node));
if(NULL == *head)
{
printf("创建失败!!!\n");
return ;
}
(*head)->next = (*head)->perv = NULL;
return ;
}
//双向循环链表头结点初始化
void sxHead(pNode *sxhead)
{
*sxhead = (pNode)malloc(sizeof(Node));
if(NULL == *sxhead)
{
printf("创建失败!!!\n");
return;
}
(*sxhead)->next = (*sxhead)->perv = *sxhead;
return ;
}
//求链表长度
int length(pNode head)
{
pNode list = head;
int sum = 0;
for(; list->next != NULL; sum++, list = list->next);
return sum;
}
//头插
void HeadInsert(pNode head, nodetype data)
{
pNode new = (pNode)malloc(sizeof(Node));
if(NULL == new)
{
printf("创建失败!!!\n");
return;
}
new->data = data;
new->next = new->perv = NULL;
new->next = head->next;
new->perv = head;
if(head->next != NULL)
head->next->perv = new;
head->next = new;
printf("插入成功。\n");
return;
}
//尾插
void weiInsert(pNode head, nodetype data)
{
pNode new = (pNode)malloc(sizeof(Node));
if(NULL == new)
{
printf("创建失败!!!\n");
return;
}
new->data = data;
new->next = new->perv = NULL;
pNode list = head;
while(list->next != NULL)
{
list = list->next;
}
new->perv = list;
list->next = new;
printf("插入成功。\n");
return;
}
//按位置插入
void PlaceInsert(pNode head, nodetype data)
{
pNode new = (pNode)malloc(sizeof(Node));
if(NULL == new)
{
printf("创建失败!!!\n");
return;
}
new->data = data;
new->next = new->perv = NULL;
pNode list = head;
int len = length(head);
int s = 0;
while(1)
{
printf("位置范围:1~%d。\n", len+1);
printf("请输入需要插入的位置:");
scanf("%d", &s);
if(s >= 1 && s <= len+1)
{
for(int i = s; i > 1; i--)//查找到插入位置的前一个节点
{
list = list->next;
}
new->next = list->next;
new->perv = list;
if(list->next != NULL)
list->next->perv = new;
list->next = new;
printf("插入成功。\n");
return;
}
else
{
printf("输入的位置有误,请重新输入!!!\n");
}
}
return;
}
//头删
void HeadClean(pNode head)
{
if(NULL == head->next)
{
printf("链表为空!!!\n");
return;
}
pNode clean = head->next;
head->next = head->next->next;
if(head->next != NULL)
head->next->perv = head;
clean->next = clean->perv = NULL;
free(clean);
printf("删除成功。\n");
return ;
}
//尾删
void WeiClean(pNode head)
{
if(NULL == head->next)
{
printf("链表为空!!!\n");
return;
}
pNode list = head;
while(list->next != NULL)
{
list = list->next;
}
list->perv->next = NULL;
list->perv = NULL;
free(list);
printf("删除成功。\n");
return ;
}
//按位置删除
void PlaceClean(pNode head)
{
if(NULL == head->next)
{
printf("链表为空!!!\n");
return;
}
pNode list = head;
pNode clean;
int s = 0;
int len = length(head);
printf("位置范围:1~%d。\n", len);
printf("请输入删除的位置:");
scanf("%d", &s);
if(s >= 1 && s <= len+1)
{
for(int i = s; i > 1; i--)//找到需要删除节点的前一个节点
{
list = list->next;
}
clean = list->next;
list->next = list->next->next;
if(list->next != NULL)
list->next->perv = list;
free(clean);
printf("删除成功。\n");
}
else
{
printf("输入位置有误,请重新输入!!!\n");
}
}
//遍历
void bianli(pNode head)
{
pNode list = head;
if(NULL == list->next)
{
printf("链表为空!!!\n");
return;
}
while(list->next != NULL)
{
printf("%d ", list->next->data);
if(list->next->next != NULL)
printf("-> ");
list = list->next;
}
printf("\n");
return;
}