使用栈 实现进制转换
头文件 .h文件
#ifndef HAHA_H
#define HAHA_H
#include <myhead.h>
typedef int datatype; //数据类型
#define MAX 20 //顺序栈最大容量
typedef struct
{
datatype *data; //存储栈的容器,指向堆区空间
int top; //记录栈顶元素的下标
} Stack, *StackPtr;
//创建栈
StackPtr stack_create();
//判空
int stack_empty(StackPtr S);
//判满
int stack_full(StackPtr S);
//入栈
void stack_push(StackPtr S, datatype e);
//出栈
void stack_pop(StackPtr S);
#endif
函数的封装 .c文件
#include "1.h"
//创建栈
StackPtr stack_create()
{
//在堆区申请一个栈的大小
StackPtr S = (StackPtr)malloc(sizeof(Stack));
if (NULL == S)
{
printf("创建失败\n");
return NULL;
}
//程序执行至此,表示栈申请出来了,但是存储栈的空间没有申请
S->data = (datatype *)malloc(sizeof(datatype) * MAX);
if (NULL == S->data)
{
printf("创建失败\n");
return NULL;
}
//给空间内容初始化
//memset(S->data,0,sizeof(datatype)*MAX);
bzero(S->data, sizeof(datatype) * MAX);
//栈顶元素变量初始化
S->top = -1;
printf("创建成功\n");
return S;
}
//判空
int stack_empty(StackPtr S)
{
return S->top == -1;
}
//判满
int stack_full(StackPtr S)
{
return S->top ==MAX - 1;
}
//入栈
void stack_push(StackPtr S, datatype e)
{
//判断逻辑
if (NULL == S || stack_full(S))
{
printf("入栈失败\n");
return;
}
//入栈逻辑
S->top++; //偏移栈顶数据
S->data[S->top] = e; //将数据压入栈中
//printf("入栈成功\n");
}
//出栈
void stack_pop(StackPtr S)
{
//判断逻辑
if (NULL == S || stack_empty(S))
{
printf("出栈失败\n");
return;
}
//出栈逻辑:先弹后减
printf("%d出栈成功\n", S->data[S->top]);
S->top--;
}
主函数 main.c
#include <myhead.h>
#include "1.h"
int main()
{
//调用创建函数,创建一个栈
StackPtr S = stack_create();
if (NULL == S)
{
return -1;
}
//进制转换
int a = 0;
int b = 0;
printf("请输入一个整数和进制数(进制数应在2到16之间): ");
scanf("%d %d", &a, &b);
// 验证进制数是否在有效范围内
if (b < 2 || b > 16)
{
printf("进制数必须在2到16之间\n");
return 0;
}
int count = 0;
while (a > 0)
{
int c = a % b;
if (c < 10)
{
stack_push(S, c); // 直接存储数字
}
else
{
// 对于10以上的数字,转换为对应的字符(A-F)
stack_push(S, c - 10 + 'A');
}
a = a / b;
count++;
}
//出栈
printf("转换后的%d进制数为: ", b);
for (int i = 0; i < count; i++)
{
if (S->data[S->top] >= 'A')
{
// 如果是字符,直接打印
printf("%c", S->data[S->top]);
}
else
{
// 如果是数字,转换为字符后打印
printf("%d", S->data[S->top]);
}
S->top--;
}
printf("\n");
return 0;
}
用循环列表实现约瑟夫环
#include <stdio.h>
#include <stdlib.h>
// 链表节点定义
typedef struct ListNode {
char data;
struct ListNode *next;
} ListNode;
// 创建一个新节点
ListNode* createNode(char data) {
ListNode *newNode = (ListNode*)malloc(sizeof(ListNode));
if (!newNode) return NULL;
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// 将节点插入到循环链表的尾部
void insertTail(ListNode **head, char data) {
ListNode *newNode = createNode(data);
if (!*head) {
*head = newNode;
newNode->next = *head; // 使其成为循环链表
} else {
ListNode *temp = *head;
// 找到尾节点
while (temp->next != *head) {
temp = temp->next;
}
temp->next = newNode;
newNode->next = *head; // 连接到头节点,形成循环
}
}
// 约瑟夫环问题的解决方案
char josephus(ListNode **head, int n, int m) {
if (!head || !*head || n < 1 || m < 1) return '\0';
ListNode *prev = NULL, *current = *head, *tail = NULL;
// 找到尾节点
for (int i = 0; i < n - 1; i++) {
tail = current;
current = current->next;
}
// 开始删除节点
while (current != current->next) { // 当链表中不止一个节点时
// 计数到 m-1
for (int count = 0; count < m - 1; count++) {
prev = current;
current = current->next;
}
// 删除当前节点
prev->next = current->next;
// 如果当前节点是尾节点,则更新尾节点
if (current == tail) {
tail = prev;
}
// 释放内存
free(current);
current = prev->next; // 移动到下一个要删除的节点
}
// 链表中只剩下一个节点,即最后的赢家
char winner = current->data;
free(current); // 释放最后一个节点
*head = NULL; // 重置头指针(可选)
return winner;
}
int main() {
ListNode *head = NULL;
int n, m;
char data;
printf("输入环的长度: ");
scanf("%d", &n);
printf("输入步长: ");
scanf("%d", &m);
printf("依次输入环内数据:\n");
for (int i = 0; i < n; i++) {
scanf(" %c", &data); // 注意前面有个空格来跳过任何之前的换行符
insertTail(&head, data);
}
printf("环内数据为: ");
ListNode *temp = head;
if (head) {
do {
printf("%c ", temp->data);
temp = temp->next;
} while (temp != head);
printf("\n");
}
char winner = josephus(&head, n, m);
printf("最后留下的赢家为: %c\n", winner);
return 0;
}