06_循环单链表

一、什么是循环单链表?
就是尾节点的next指针域存放的是头节点的地址
二、需要使用的函数?
1、必备函数
(1)判断链表是否为空

(2)判断addr是否在链表中

(3)求链表长度

(4)定位到addr的前一个节点

(5)新建一个节点

(6)增加一个节点

(7)删除一个节点
2、基础函数
(1)初始化链表

(2)根据元素返回addr

(3)插入一个新的元素

(4)遍历链表

(5)删除指定元素
//3、插入一个新的元素
Status insert_elem(LinkedList head, int addr, ElemType elem){

    //2、新建一个节点
    Node * pNew = new_node();
    pNew->data = elem;

    //3、定位
    Node * temp = locat_before_node(head, addr);

    //4、插入节点
    insert_node(temp,pNew);

    return Ok;
}
//4、遍历链表
void traverse_list(LinkedList head){
    Node * temp = head->next;
    while (temp){
        if (temp == head)
            break;
        printf("%-4d",temp->data);
        temp = temp->next;
    }
    printf("\n");
}
三、总结
单循环链表和单链表的操作是相似的,唯一的区别就是插入元素、遍历元素

1、掌握基础函数
2、掌握必备函数
3、熟悉循环单链表 和 单链表在基础操作上的区别
四、代码
// Created by hanfei on 2021/5/4.
// 创建循环链表
//循环链表
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define ElemType int
#define Status int
#define Error 0
#define Ok 1

typedef struct node{
    ElemType data;
    struct node * next;
}Node, * LinkedList;

/***********************必备函数***********************/
//1、判断链表是否为空
bool isEmpty(LinkedList head){

    if(head->next == head){
        printf("The list is empty\n");
        return true; //为空
    }
    return false; //不为空
}

//2、求链表长度
int length_list(LinkedList head){

    Node * temp = head->next;
    int length = 0;
    if (temp != head)
    {
        while(temp){
            length++;
            temp = temp->next;
            if (temp == head)
            {
                break;
            }
        }
    }

    return length;
}

//3、判断addr是否在区间中
bool isBetween(LinkedList head, int addr){

    if (addr<1 || addr>length_list(head))
    {
        printf("The addr is not in the list!\n");
        return false; //不在区间中
    }
    return true; //在区间中
}

//5、新建一个节点
Node * new_node(){
    Node * node = (Node *)malloc(sizeof(Node));
    if (node == NULL)
    {
        printf("Failed to create node\n");
        exit(1);
    }
    node->next = NULL;
    return node;
}

//6、插入一个节点
void insert_node(Node * before_node, Node * after_node){

    after_node->next = before_node->next;

    before_node->next = after_node;

}

//7、删除一个节点
void delete_node(Node * before_node, Node * after_node){

    if (before_node->next->next == before_node)
    {
        before_node->next = NULL;
        before_node->next = before_node;
        free(after_node);
    }else{
        Node * temp = after_node;

        before_node->next = after_node->next;

        free(after_node);
    }

}

//8、定位到前一个节点
Node * locat_before_node(LinkedList * head, int addr){
    Node * temp = head;
    for (int i = 1; i < addr; i++)
    {
        temp = temp->next;
    }
    return temp;
}


/***********************基础函数***********************/
//1、初始化链表
Node * init_list(){
    Node * head = (Node *)malloc(sizeof(Node));

    if (head == NULL)
    {
        printf("Initialization failed!\n");
        exit(1);
    }

    head->next = head;

    return head;
}

//2、根据元素返回addr
int search_by_elem(LinkedList head, ElemType elem){

    //1、判断
    if(isEmpty(head)){
        return 0;
    }

    //2、查找
    Node * temp = head->next;
    int addr = 1;
    while (temp)
    {
        //1、判断
        if (temp == head)
        {
            printf("The element is not in the list!\n");
            return 0;
        }

        //2、求长度
        if (temp->data == elem)
        {
            return addr;
        }
        temp = temp->next;
        addr++;
    }

    return 0;
}

//3、插入一个新的元素
Status insert_elem(LinkedList head, int addr, ElemType elem){

    //2、新建一个节点
    Node * pNew = new_node();
    pNew->data = elem;

    //3、定位
    Node * temp = locat_before_node(head, addr);

    //4、插入节点
    insert_node(temp,pNew);

    return Ok;
}

//4、遍历链表
void traverse_list(LinkedList head){
    Node * temp = head->next;
    while (temp){
        if (temp == head)
            break;
        printf("%-4d",temp->data);
        temp = temp->next;
    }
    printf("\n");
}
//5、删除指定元素
Status delete_elem(LinkedList head, ElemType elem){

    //1、判断
    if (isEmpty(head)){
        return Error;
    }

    //2、定位
    int addr = search_by_elem(head, elem);

    Node * temp = locat_before_node(head,addr);

    //3、删除节点
    delete_node(temp,temp->next);

    return Ok;
}

//6、总结:根据addr进行的元素操作暂时不需要进行

int main(void){
    Node * head = init_list();
    insert_elem(head,1,1);
    insert_elem(head,2,2);
    insert_elem(head,3,3);
    insert_elem(head,4,5);
    traverse_list(head);
    delete_elem(head,1);
    traverse_list(head);
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_43876924

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值