数据结构第3天作业

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;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值