关于约瑟夫循环使用单链表的问题

本文介绍如何使用C++实现单链表的数据结构,包括链表的创建与节点的删除过程。通过malloc和new操作符分配内存,创建循环单链表,并实现了基于特定规则剔除链表中节点的功能。
#include <iostream>
//#include<malloc.h>      //分配长度为num_bytes字节的内存块,如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
                                      //当内存不再使用时,应使用free()函数将内存块释放。
using namespace std;
typedef struct Node
{
    int data;
    struct Node *next;
}ListNode,*LinkList;

/*
  LinkList L;
       L=malloc(sizeof(LinkList));
       是指申请一个链表的头结点的空间,并使该链表的指针指向该结点。
       因为理论上说链表空间可以无限,即整个内存的空间都可以为其所用,
       所以无需提前指定链表空间大小也可以继续申请下一个结点的空间。
       ListNode*p;
       p=malloc(sizeof(LNode));
       与上句不同,这句是指你申请一个结点的空间。LNode*p;是先定义一个结点。
       p=malloc(sizeof(LNode));是指为该结点申请内存空间.
*/
      // 注意一个结点和一个链表的区别就可以了。
LinkList Found(int n);      //建立一个n个人员的单链表
void Remove(LinkList &head,int n,int m,int k);      //剔除人员并输出最后剩余的一位人员
int main()
{
    int n = 0 , m = 0 , k = 0;
    cout << "请输入人员个数n=";
    cin>>n;
    cout<<"请输入剔除一人的间距m=";
    cin>>m;
    cout<<"请输入剔除开始从第k为人,k=";
    cin>>k;
    LinkList head=NULL;      //创建头指针为head的链表(是链表不是结点)
    head=Found(n);      //调用函数生成单链表
    /*
          for(int i=0;i<n;i++)
         {
                cout<<head->data<<endl;
                head=head->next;
         }
    */          //测试链表head是否建立
    Remove(head,n,m,k);      //调用函数剔除人员并输出最后剩余的一位人员
    return 0;
}
LinkList Found(int n)
{
    LinkList head=NULL;      //头指针,也可以代表整个单链表
    LinkList s,r;
    for(int i=0;i<n;i++)
    {
        //s=(LinkList)malloc(sizeof(ListNode));      使用malloc函数创建对象ListNode(结点)指针
        s=new ListNode;      //c++使用new来创建空间并赋值指针s
        if(head==NULL)
            head=s;
        else
            r->next=s;
        r=s;
        r->data=i+1;
    }
    r->next=head;      //单链表循环
    return head;
}
void Remove(LinkList &head,int n,int m,int k)
{
    int s=1,i;
    ListNode *p,*q;      //p,q两个结点指针,用于删除人员
    p=head;
    q=p->next;
    for(i=1;i<k;i++)
    {
        p=q;
        q=q->next;
    }
    while(p->next!=p)
 {
  for(i=1;i<m-1;i++) //数到m-1的人
  {
   p=q;
   q=q->next;
  }
  cout<<"剔除第"<<s++<<"位人员:";   //先输出的s,然后s++。
  cout<<p->next->data<<" "<<endl;
  p->next=q->next; //报数为m的人剔除
  delete  q;      //释放q,q指向的结点被删除
  //free(q);
  p=p->next;   //p指向下一个结点,重新开始报数
  q=p->next;
 }
    cout<<endl<<"最后一位人为"<<p->data<<endl;
}

转载于:https://www.cnblogs.com/XingPengJu/p/9761696.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值