1、使用单向循环链表完成约瑟夫环问题
约瑟夫环:用循环链表编程实现约瑟夫问题
n个人围成一圈,从某人开始报数1, 2, …, m,数到m的人出圈,然后从出圈的下一个人(m+1)开始重复此过程,直到全部人出圈,于是得到一个出圈人员的新序列
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
typedef struct Node
{
union
{
int data;
int len;
};
struct Node *next;
}Node,*LinkedList;
//创建链表
LinkedList create_list()
{
LinkedList header=(LinkedList)malloc(sizeof(Node));
if(header!=NULL)
{
header->len=0;
header->next=header;
}
return header;
}
//展示链表
void printf_list(LinkedList L)
{
LinkedList p=L;
if(L==NULL)
{
return;
}
//如果链表有效,循环p指向下一个结点,直到p指向头结点为止
while((p=p->next)!=L) //循环遍历
{
printf("%d\t",p->data);
}
printf("\n");
}
//尾插
int insert_back(LinkedList L,int e)
{
if(L==NULL)
{
return 0;
}
//循环n次(n表示链表长度)找到最后一个结点
LinkedList pt=L;
for(int i=0;i<L->len;i++)
{
pt=pt->next;
}
//创建新结点并插入到最后
LinkedList p=(LinkedList)malloc(sizeof(Node));
if(p==NULL)
{
printf("分配新结点内存失败\n");
return 0;
}
//给新结点赋值数据域
p->data=e;
//尾插逻辑
p->next=L;
pt->next=p;
//表长变化
L->len++;
return 1;
}
void josepho(LinkedList L,int k)
{
LinkedList pt=L,q;
if(L==NULL)
{
//链表空
return;
}
//n个人循环n次,n等于链表长度
int n=L->len;
for(int i=0;i<n;i++)
{
//循环k-1次找到要删除的前一个结点
for(int j=0;j<k-1;j++)
{
pt=pt->next;
//如果找到的是头结点,绕过 (但循环次数加1)
if(pt==L)
{
j--;
}
}
// q是要删除的结点
q=pt->next;
// 如果删除的结点q是头结点,绕过
if(q==L)
{
q=L->next;
pt = L;
}
//删除
printf("%d\t",q->data);
pt->next=q->next; //孤立要删除的节点
free(q); //释放要删除的节点
L->len--;
}
}
//主函数
int main()
{
LinkedList L=create_list();
int i=1,e;
//输入0或负数结束输入
printf("请输入第%d个人员的编号:",i++);
scanf("%d",&e);
while(e>0)
{
insert_back(L,e);
printf("请输入第%d个人员的编号:",i++);
scanf("%d",&e);
}
printf("\n参与游戏的人员编号:\n");
printf_list(L);
//输入k值,并调用约瑟夫环函数计算出圈次序
int k;
printf("请输入数到几出列:") ;
scanf("%d",&k);
printf("\n依次出圈的人员编号是:\n");
josepho(L,k);
return 0;
}
运行结果:
2、使用栈的操作完成进制转换问题,例如输入一个十进制数据,程序输出该数据的二进制
//十进制转换为二进制
void stack_10_2(StackPtr S)
{
int n;
scanf("%d",&n);
if(n==0)
{
printf("二进制数为:0\n");
return;
}
//将十进制逐位取余并进栈
while(n>0)
{
if(n%2!=0)
{
stack_push(S,1);
}
else if(n%2==0)
{
stack_push(S,0);
}
n/=2;
}
printf("从栈顶到栈底元素分别是:");
for(int i=S->top;i>=0;i--)
{
printf("%d\t",S->data[i]);
}
putchar(10);
}
进阶
void converse(SqStack *s,int num, int m) //num是要转化的数, m表示的是进制数
{
int mod; //余数
while(num!=0)
{
mod=num%m;
push(s,mod);
num=num/m;
}
while(s->top!=-1)
{
pop(s);
}
}
运行结果