链表的应用:用循环链表解决约瑟夫问题

洛谷题目链接:洛谷P1996

#include
using namespace std;
struct node
{
    long d;
    node *next;
};
long n, m;
node *head, *p, *r;
int main()
{
    long i, j, k, l;
    cin >> n >> m;
    head = new node;
    head -> d = 1;
    head -> next = NULL;
    r = head;
    for(i=2;i<=n;i++)
    {
        p = new node;
        p -> d = i;
        p -> next = NULL;
        r -> next = p;
        r = p;
    }
    r -> next = head;
    r = head;
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m-2;j++) r = r -> next;
        cout << r->next->d << " ";
        r ->next = r->next->next;
        r = r->next;
    }
    cout << endl;
    return 0;
}

在学校的老师提供了一份解决约瑟夫环的问题的代码,只针对13个人遇5出圈的特殊问题,附在这里是为了学习一下其通用性的代码风格:
(说实话那个变量名称如此之长以至于写的很崩溃)

#include
#include

#define ElementType int
typedef struct listNode
{
    ElementType data;
    struct listNode *nextPtr;
}LISTNODE;
typedef LISTNODE *  LISTNODEPTR;


#define N 13
#define M 5
void insertCirEnd2(LISTNODEPTR *lastPtrPtr, ElementType value);
void printCirList(LISTNODEPTR headPtr);
void destroyCirList(LISTNODEPTR * headPtrPtr);

int main()
{
    int i, j;
    LISTNODEPTR headPtr = NULL, lastPtr = NULL;
    headPtr = (LISTNODEPTR)malloc(sizeof(LISTNODEPTR));//先建立起头结点
    if(headPtr!=NULL)
    {
        headPtr -> nextPtr = headPtr;//通过这种方式建立起环形链表
        lastPtr = headPtr;
    }
    else 
    {
        printf("List not created. No memory available.\n\n");
        return 0;
    }

    for(i=1;i<=N;i++)
        insertCirEnd2(&lastPtr, i);//建立起基本链表
    printCirList(headPtr);

    LISTNODEPTR currentPtr, previousPtr;
    currentPtr = headPtr -> nextPtr;
    previousPtr = headPtr;
    for(j=1;j<=(N-1)*M;j++)
    {
        if(currentPtr == headPtr)
        {
            previousPtr = currentPtr;
            currentPtr = currentPtr -> nextPtr;
        }
        if(j%M==0)
        {
            previousPtr->nextPtr = currentPtr->nextPtr;
            printf("j=%d, delete %d, pre=%p, next = %d\n", j, currentPtr->data, previousPtr,previousPtr->nextPtr->data);
            free(currentPtr);
            printCirList(headPtr);
            currentPtr = previousPtr->nextPtr;
        }
        else
        {
            previousPtr = currentPtr;
            currentPtr = currentPtr -> nextPtr;
        }
        
    }
    printCirList(headPtr);
    destroyCirList(&headPtr);
    return 0;
}

void insertCirEnd2(LISTNODEPTR *lastPtrPtr, ElementType value)
{
    LISTNODEPTR newPtr;
    newPtr = malloc(sizeof(LISTNODEPTR));
    if(newPtr != NULL)
    {
        newPtr -> data = value;
        newPtr -> nextPtr = (* lastPtrPtr) -> nextPtr;
        (*lastPtrPtr) -> nextPtr = newPtr;
        *lastPtrPtr = newPtr;
    }
    else printf("Not inserted. No memory avaliable.\n");
    return ;
}

void printCirList(LISTNODEPTR headPtr)
{
    LISTNODEPTR currentPtr;
    currentPtr = headPtr -> nextPtr;
    if(currentPtr==NULL) printf("List is empty\n");
    else
    {
        printf("The list is:\n");
        while(currentPtr != headPtr)
        {
            printf("%d-->", currentPtr->data);
            currentPtr = currentPtr -> nextPtr;
        }
        printf("END\n\n");
    }
}   

void destroyCirList(LISTNODEPTR * headPtrPtr)
{
    LISTNODEPTR tempPtr, currentPtr;
    currentPtr = (*headPtrPtr) -> nextPtr;
    while(currentPtr != *headPtrPtr)
    {
        tempPtr = currentPtr;
        currentPtr = currentPtr -> nextPtr;
        free(tempPtr);
    }
    free(*headPtrPtr);
    *headPtrPtr = NULL;
}

你可能感兴趣的:(链表)