单向循环链表的实现以及基本功能

1、单向循环链表的实现以及基本功能



/**
 *    由于单向循环链表和单向链表基本一样,因此大部分代码我直接复制粘贴单向链表的代码
 *    我们只需要把 p->next = NULL或者p = NULL 这两个条件改为 p->next = LL或者p = L 就可以啦
 *
 */

#include<stdio.h>
#include <mm_malloc.h>

#define MAXSIZE 15   // 常量的定义不需要分号也不需要等号  MAXSIZE = 5; 这样是错误的
#define OK  1
#define ERROR -1
#define NOTFOUND -2

typedef struct Node{

    char data;
    struct Node *next;

}Node,*LinkList;


/*int main(){
    LinkList creatLinkList();
    void createFromHead(LinkList L);
    void dispaly(LinkList L);
    void createFormTail(LinkList L);
    int getLinkListLength(LinkList L);
    int insert(LinkList L ,char elem,int index);
    int delete(LinkList L ,int index);
    int getElem(LinkList L,int index);
    int getIndex(LinkList L,char elem);
    LinkList createFormTailReturnTail(LinkList L);

    LinkList L = creatLinkList();
   LinkList RA = createFormTailReturnTail(L);
    dispaly(RA->next);




}*/

//初始化单向链表
LinkList creatLinkList(){
    Node *p = (Node *)malloc(sizeof(Node));
    p->next = NULL;
    return p;
};

//尾插法建立单向表
void createFormTail(LinkList L){
    Node *p,*r;
    r = L;
    char c;
    int flag = 1;
    while(flag){
        c = getchar();
        if (c != '$'){
            p = (Node *)malloc(sizeof(Node));
            p->data = c;
            r->next = p;
            r = p;
        }else{
            r->next = L;
            flag = 0;
        }
    }
}

//尾插法建立单向表,并返回尾指针
LinkList createFormTailReturnTail(LinkList L){
    Node *p,*r;
    r = L;
    char c;
    int flag = 1;
    while(flag){
        c = getchar();
        if (c != '$'){
            p = (Node *)malloc(sizeof(Node));
            p->data = c;
            r->next = p;
            r = p;
        }else{
            r->next = L;
            flag = 0;
        }
    }
    return r;
}

//遍历单向链表
void dispaly(LinkList L){
    Node *p = L;
    while (p->next != L){
        p = p->next;
        printf("%c\t",p->data);
    }
}

//得到单向链表的长度
int getLinkListLength(LinkList L) {
    Node *p = L;
    int length = 0;
    while (p->next != NULL) {
        p = p->next;
        length++;
    }
    return length;
}

//插入数据 返回1表示成功,-1表示失败
int insert(LinkList L ,char elem,int index){

    //插入为位置小于1肯定是不对的,毫无疑问的
    if (index < 1){
        printf("输入的位置不对!");
        return ERROR;
    }

    Node *pre,*r;
    pre = L;
    int j = 0;

    while(pre != L && j < index-1){//这是成立的条件,当遍历完还没找到插入的位置或者是找到插入的位置都跳出循环
        pre = pre ->next;
        j++;
    }

    if (pre == L){ //由于while循环结束肯能是因为pre ==NULL造成的所以要判断一下
        printf("插入的位置过大!");
        return ERROR;

    }

    //到达这一步肯定是意味着来到了
    r = (Node *)malloc(sizeof(Node));
    r->data = elem;
    r->next = pre->next;
    pre->next = r;
    return OK;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您解答。首先,我们需要了解猴子选大王的规则: 1. N只猴子(N>1)围成一圈,从1开始按顺序编号。 2. 从第1只猴子开始报数,从1开始报数,数到M的猴子出列,剩下的猴子重新围成一圈,从下一只猴子开始继续报数,直到最后只剩下一只猴子为止,那么这只猴子就是大王。 现在我们来设计一个单向循环链表实现这个过程。首先,我们可以定义一个 Monkey 类,表示每只猴子: ``` class Monkey: def __init__(self, num): self.num = num self.next = None ``` 其中,num 表示猴子的编号,next 表示下一只猴子的指针。接下来,我们可以定义一个 MonkeyCircle 类,表示猴子围成的圈: ``` class MonkeyCircle: def __init__(self, n, m): self.head = Monkey(1) p = self.head for i in range(2, n+1): p.next = Monkey(i) p = p.next p.next = self.head self.m = m ``` 其中,n 表示猴子的数量,m 表示报数的数字。在初始化时,我们创建一个头结点,然后依次创建剩下的猴子节点,并将最后一个猴子节点的 next 指针指向头结点,形成一个循环链表。 接下来,我们可以定义一个方法,模拟猴子选大王的过程: ``` def choose_king(self): p = self.head while p.next != p: for i in range(self.m-1): p = p.next p.next = p.next.next return p.num ``` 在这个方法中,我们使用一个 while 循环来不断地遍历链表,直到只剩下一只猴子为止。在每次循环中,我们使用一个 for 循环来报数,每数到第 m 只猴子,就将它从链表中删除。最后,剩下的那只猴子就是大王。 完整代码如下: ``` class Monkey: def __init__(self, num): self.num = num self.next = None class MonkeyCircle: def __init__(self, n, m): self.head = Monkey(1) p = self.head for i in range(2, n+1): p.next = Monkey(i) p = p.next p.next = self.head self.m = m def choose_king(self): p = self.head while p.next != p: for i in range(self.m-1): p = p.next p.next = p.next.next return p.num ``` 希望能够解答您的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值