数据结构学习笔记(4)循环链表

本文介绍了如何使用循环链表数据结构实现约瑟夫环问题,并提供了完整的代码示例,包括初始化、插入、删除和获取元素功能,以及约瑟夫环的构建和执行。通过这个案例,读者可以学习到链表操作技巧和算法在实际问题中的应用。
摘要由CSDN通过智能技术生成

完整代码+测试函数+约瑟夫环

目录

CircularList.h

CircularList.c

Test.c

JC.c


CircularList.h

#pragma once
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef int DataType;

//定义结构体
typedef struct Node
{
	DataType data;
	struct Node* next;
}SLNode;

//初始化循环链表
void CircularListInitiate(SLNode** head);


//求当前数据元素的个数
int CircularListLength(SLNode* head);


//插入CircularList(SLNode* head插入的链表,int i插入的位置,DataType x插入的数据)
int CircularListInsert(SLNode* head, int i, DataType x);


//删除CircularListDelete(SLNode*head,int i,DataType *x用来保存删除的数据元素)
int CircularListDelete(SLNode* head, int i, DataType* x);


//取数据元素
int CircularListGet(SLNode* head, int i, DataType* x);


//撤销循环链表
void Destory(SLNode** head);

CircularList.c

#include<stdio.h>
#include<stdlib.h>
#include"CircularList.h"

//初始化循环链表
void CircularListInitiate(SLNode** head)
{
	*head = (SLNode*)malloc(sizeof(SLNode));
	(*head)->next = *head;
}

//求当前数据元素的个数
int CircularListLength(SLNode* head)
{
	SLNode* p = head;
	int size = 0;
	while (p->next != head)
	{
		p = p->next;
		size++;
	}
	return size;
}

//插入CircularList(SLNode* head插入的链表,int i插入的位置,DataType x插入的数据)
int CircularListInsert(SLNode* head, int i, DataType x)
{
	SLNode* p = head;
	SLNode* q;//生成新结点用q标记
	int j = -1;

	while (p->next != head && j < i - 1)
	{
		p = p->next;
		j++;
	}

	if (j != i - 1)
	{
		printf("输入位置无效");
		return 0;
	}

	q = (SLNode*)malloc(sizeof(SLNode));
	q->data = x;

	q->next = p->next;
	p->next = q;
	return 1;
}

//删除CircularListDelete(SLNode*head,int i,DataType *x用来保存删除的数据元素)
int CircularListDelete(SLNode* head, int i, DataType* x)
{
	SLNode* p = head;
	SLNode* q;//被删除的结点
	int j = -1;

	while (p->next->next != head && j < i - 1 && p->next != head)
	{
		p = p->next;
		j++;
	}
	if (j != i - 1)
	{
		printf("输入位置错误");
		return 0;
	}

	q = p->next;
	*x =q->data;
	p->next = p->next->next;
	free(q);
	return 1;
}

//取数据元素
int CircularListGet(SLNode* head, int i, DataType* x)
{
	SLNode* p = head;
	int j = -1;
	while (p->next != head && j < i)
	{
		p = p->next;
		j++;
	}
	if (j != i)
	{
		printf("取元素位置错误");
		return 0;
	}

	*x = p->data;
	return 1;
}

//撤销循环链表
void Destory(SLNode** head)
{
	SLNode *p, *q;
	p = *head;
	while (p != NULL)
	{
		q = p;
		p = p->next;
		free(q);	
	}
	*head = NULL;
}

Test.c

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include"CircularList.h"

 void main()
{
	SLNode* head;
	int i, x;

	CircularListInitiate(&head);
	for ( i = 0; i < 10; i++)
	{
		CircularListInsert(head, i, i + 1);
	}
	CircularListDelete(head,4,&x);
	printf("%d\n", x);
	//构建完成,对链表数据逐个输出
	for (i = 0; i < CircularListLength(head); i++)
	{
		CircularListGet(head,i,&x);
		printf("%d  ",x);
	}
	Destory(&head);
}

JC.c

//约瑟夫环

#include <stdio.h>
#include <stdlib.h>

typedef struct node {
    int number;
    struct node* next;
}person;

//构建约瑟夫环
person* ListStructure(int n) 
{
    person* head = (person*)malloc(sizeof(person));
    head->number = 1;
    head->next = NULL;
    person* p = head;
    for (int i = 2; i <= n; i++) {
        person* q = (person*)malloc(sizeof(person));
        q->number = i;
        q->next = NULL;
        p->next = q;
        p= p->next;
    }
    p->next = head;//首尾相连
    return head;
}

//执行出环
void Execute(person* head, int k, int m) 
{

    
       
    person* pre=head;//pre始终指向p的前一个结点
      
        person* p = head;//p指向开始位置的结点
        
        //找到编号为k的人
    while (p->number != k) {
        pre = p;
        p = p->next;
    }
    //从编号为k的人开始,只有符合p->next==p时,说明链表中除了p结点,所有编号都出列了,
    while (p->next != p) {
        
        for (int i = 1; i < m; i++) {
            pre = p;
            p = p->next;
        }
        pre->next = p->next;//删除链表上的p结点
        printf("出列人的编号为:%d\n", p->number);
        free(p);
        p = pre->next;//继续使用p指针指向出列编号的下一个编号
    }
    printf("出列人的编号为:%d\n", p->number);
    free(p);
}

int main() {
    printf("输入圆桌上的人数n:");
    int n;
    scanf_s("%d", &n);
    
    person* head = ListStructure(n);

    printf("从第k人开始报数(k>1且k<%d):", n);
    int k;
    scanf_s("%d", &k);
    
        
    
    while (k > n)
    {
        printf("输入位置错误,请重新输入");
        scanf_s("%d", &k);
    }
    
    printf("数到m的人出列:");
    int m;
    scanf_s("%d", &m);
   
   Execute(head, k, m);
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值