循环链表的理论知识与api的设计实现

一、循环链表的定义:将单链表中最后一个数据元素的next指针指向第一个元素。


二、循环链表的操作:循环链表拥有单链表的所有操作。
    1. 创建链表
    2. 销毁链表
    3. 获取链表的长度
    4. 清空链表

    5. 获取pos位置的元素
    6. 插入元素到pos位置

    7. 删除pos位置的元素

三、游标的定义(新增的功能)

    在循环链表中可以定义一个“当前指针”,通常将这个指针称为游标,可以通过这个游标来遍历循环链表中的所有元素。

四、循环链表的新操作
    1. 获取循环链表当前游标指向的数据元素
    2. 将游标重置指向链表中的第一个数据元素
    3. 将游标移动指向到链表中的下一个数据元素

    4. 直接指定删除链表中的某个数据元素

五、插入元素分析,分为第一次插入元素、普通位置插入和特殊位置插入(头插、尾插)。




六、删除元素分析

七、循环链表的优缺点
    优点:循环链表在功能上比单链表强,循环链表完全可以取代单链表,循环链表可以高效的遍历表中的元素。

    缺点:代码实现的复杂度提高了

八、循环链表的典型应用
    约瑟夫问题:n 个人围成一个圆圈,首先第 1 个人从 1 开始一个人一个人顺时针报数,报到第 m 个人,令其出列。然后再从下一个人开始从 1 顺时针报数,报到第 m 个人,再令其出列,…,如此下去,求出列顺序。

九、循环链表的api设计

//头文件
#ifndef _ZCH_CIRCLELIST_H_
#define _ZCH_CIRCLELIST_H_

typedef void CircleList //数据封装
//循环链表的指针域
typedef struct _tag_CircleListNode
{
    struct _tag_CircleListNode *next;
}CircleListNode;

CircleList* Create();

void Destroy(CircleList* list);

void Clear(CircleList* list);

int Length(CircleList* list);

int Insert(CiecleList* list, CircleListNode* node, int pos);

CircleListNode* GetEle(CircleList* list , int pos);

CircleListNode* Delete(CircleList* list, int pos);

//增加功能
CircleListNode* DeleteNode(CircleList* list, CircleListNode* node);

CircleListNode* Reset(CircleList* list);

CircleListNode* Current(CircleList* list);

CircleListNode* Next(CircleList* list);

#endif

十、循环链表api的实现

#include "zch_circlelist.h"

//循环链表的抽象
typedef struct _tag_CircleList
{
    //头节点
    CircleListNode header;
    //游标	
    CircleListNode* slider;
    int length;
} TCircleList;

CircleList* Create()
{
    TCircleList* CList = (TCircleList*)malloc(sizeof(TCircleList));

    if(NULL == CList)
    {
        return NULL;
    }
    CList->length = 0;
    CList->header.next = NULL;
    CList->slider = NULL;
    return CList;
}

void Destroy(CircleList* list)
{
    if (list == NULL)
    {
	return ;
    }
    free(list);
}

void Clear(CircleList* list)
{
    TCircleList* CList = (TCircleList*)list;
    if(NULL == CList)
    {
        return ;
    }
    CList->length = 0;
    CList->hender.next = NULL;
    CList->slider = NULL;
}

int Length(CircleList* list)
{
    TCircleList* CList = (TCircleList*)list;
    if (list == NULL)
    {
	return -1;
    }
	
    return CList->length;
}

int Insert(CircleList* list, CircleListNode* node, int pos)
{
    int i = 0;
    TCircleList* CList = (TCircleList*)list;
    //辅助指针current指向头节点
    CircleListNode* current = (CircleListNode*)CList; 
    if(NULL == CList || NULL == node || pos < 0)
    {
        return -1
    }
    if(pos >= CList->length)
    {
        pos = CList->length; //默认尾插
    }
    for(i = 0; (i < pos) && (current->next != NULL); i++)
    {
        current = current->next;
    }
    node->next = current->next;
    current->next = node;
    //若是第一次插入节点
    if(CList->length == 0)
    {
    //游标指向第0号元素
        CList->slider = node;
    }
    CList->length++;

    //若是头插法
    if(current == (CircleListNode*)CList)
    {
        CircleListNode* last = GetEle(CList, CList->length - 1);
        last->next = current->next; //指向0号元素,形成循环
    }
    return 0;
}

CircleListNode* GetEle(CircleList* list, int pos)
{
    TCircleList* CList = (TCircleList*)list;
    CircleListNode* current = (CircleListNode*)CList;
    int i = 0;
    if(NULL == CList || pos < 0 || pos >= CList->length)
    {
        return NULL;
    }
    for(i = 0; i < pos; i++)
    {
        current = current->next;
    }
    return current->next;
}

CircleListNode* Delete(CircleList* list, int pos)
{
    TCircleList* CList = (TCircleList*)list;
    CircleListNode* ret = NULL;
    int i = 0;
    if((CList != NULL) && (pos >= 0) && (CList->length > 0) && (pos < CList->length))
    {
        CircleListNode* current = (CircleListNode*)CList;
        CircleListNode* last = NULL;
        for(i = 0; i < pos; i++)
        {
            current = current->next;
        }
        //若删除第一个元素
        if(current == (CircleListNode*)CList)
        {
            last = GetEle(CList, CList->length - 1);
        }
        //先将要删除的元素保存下来
        ret = current->next;
        current->next = ret->next;
        CList->length--;
        //头删
        if(last)
        {
            CList->header.next = ret->next;
            last->next = ret->next;
        }
        //若删除的元素为游标所指的元素
        if(CList->slider == ret)
        {
            CList->slider = ret->next;
        }
        //若删除元素后,链表的长度为0
        if(CList->length == 0)
        {
            CList->header.next = NULL;
            CList->slider = NULL;
        }
    }
    return ret;
}

CircleListNode* DeleteNode(CircleList* list, CircleListNode* node)
{
    TCircleList* CList = (TCircleList*)list;
    CircleListNode* ret = NULL;
    int i = 0;
    if(CList != NULL)
    {
        CircleListNode* current = (CircleListNode*)CList;
        for(i = 0; i <CList->length; i++)
        {
            //查找node在循环链表中的位置i
            if(current->next == node)
            {
                ret = current->next;
                break;
            }
            current = current->next;
        }
        //如果ret找到,根据i去是删除
        if(ret != NULL)
        {
        Delete(CList, i);
        }
    }
    return ret;
}

CircleListNode* Reset(CircleList* list)
{
    TCircleList* CList = (TCircleList*)list;
    CircleListNode* ret = NULL;
    if(CList != NULL)
    {
        CList->slider = CList->header.next;
        ret = CList->slider;
    }
    return ret;
}

CircleListNode* Current(CircleList* list)
{
    TCircleList* CList = (TCircleList)list;
    CircleListNode* ret = NULL;
    if(CList != NULL)
    {
        ret = CList->slider;
    }
    return ret;
}

CircleListNode* Next(CircleList* list)
{
    TCircleList* CList = (TCircleList*)list;
    CircleListNode* ret = NULL;
    if((CList != NULL) && (CList->slider != NULL))
    {
        ret = CList->slider;
        CList->slider = ret->next;
    }
    return ret;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值