双向循环带头链表基本操作总结

定义类型
typedef int CLDataType;
//结点类型
typedef struct ListNode
{
    CLDataType _data;
    struct ListNode* _next;
    struct ListNode* _prev;
}ListNode;
//链表类型
typedef struct List
{
    ListNode* _head;
}List;
函数声明
//初始化双向循环带头链表
void ListInit(List* pcl);
//销毁双向循环带头链表
void ListDestory(List* pcl);
//尾插
void ListPushBack(List* pcl, CLDataType x);
//头插
void ListPushFront(List* pcl, CLDataType x);
//指定位置插入结点 
void ListInsert(ListNode* pos, CLDataType x);
//尾删
void ListPopBack(List* pcl);
//头删
void ListPopFront(List* pcl);
//指定位置删除(不能是头结点)
void ListErase(List* pcl, ListNode* pos);
//遍历打印链表
void ListPrint(List* pcl);
//链表的长度
int ListSize(List* pcl);
//判断链表是否为空(为空返回0,非空返回1)
int ListEmpty(List* pcl);
//寻找指定数据的结点(找到返回地址,找不到返回NULL)
ListNode* FindListNode(List* pcl, CLDataType x);
//创建一个双向循环链表结点
ListNode* BuyListNode(CLDataType x);
函数实现
/*************************************************************************/
/*双向循环带头链表*/
//创建一个双向循环链表结点
ListNode* BuyListNode(CLDataType x)
{
    ListNode* cur = (ListNode*)malloc(sizeof(ListNode));
    if (cur == NULL)
    {
        perror("use malloc");
    }
    cur->_data = x;
    cur->_next = NULL;
    cur->_prev = NULL;
}
//初始化双向循环带头链表
void ListInit(List* pcl)
{
    assert(pcl);
    ListNode* head = BuyListNode(0);
    pcl->_head = head;
    pcl->_head->_next = pcl->_head;
    pcl->_head->_prev = pcl->_head;
}
//销毁双向循环带头链表
void ListDestory(List* pcl)
{
    assert(pcl);
    ListNode* cur = pcl->_head;
    while (cur != pcl->_head)
    {
        ListNode* tmp = cur->_next;
        free(cur);
        cur = tmp;
    }
    free(pcl->_head);
    pcl->_head = NULL;
}
//尾插
void ListPushBack(List* pcl, CLDataType x)
{
    assert(pcl);
    //尾插和在头结点前面插入一个结点一样
    ListInsert(pcl->_head, x);
}
//头插
void ListPushFront(List* pcl, CLDataType x)
{
    assert(pcl);
    //头插和在第一个结点前面插入一样
    ListInsert(pcl->_head->_next, x);
}
//指定位置前面插入结点 
void ListInsert(ListNode* pos, CLDataType x)
{
    assert(pos);
    ListNode* newnode = BuyListNode(x);
    //保存前面结点(建议这么写,如果直接用指针完会太绕了)
    ListNode* prev = pos->_prev;
    //prev newnode pos指针连接起来
    prev->_next = newnode;
    newnode->_prev = prev;
    newnode->_next = pos;
    pos->_prev = newnode;
}
//尾删
void ListPopBack(List* pcl)
{
    assert(pcl);
    //尾删和在删除指定最后一个结点一样
    ListErase(pcl, pcl->_head->_prev);
}
//头删
void ListPopFront(List* pcl)
{
    assert(pcl);
    //头删和删除指定第一个结点一样
    ListErase(pcl, pcl->_head->_next);
}
//指定位置删除结点
void ListErase(List* pcl, ListNode* pos)
{
    assert(pos);
    //删除的结点不能是头结点
    assert(pos != pcl->_head);
    //保存pos前面结点
    ListNode* prev = pos->_prev;
    //保存pos后面结点
    ListNode* next = pos->_next;
    //prev pos next(pos为删除结点) 
    prev->_next = next;
    next->_prev = prev;
    free(pos);
    pos = NULL;
}
//遍历打印链表
void ListPrint(List* pcl)
{
    assert(pcl);
    ListNode* cur = pcl->_head->_next;
    //从头结点的下一个结点开始遍历
    while (cur != pcl->_head)
    {
        printf("%d-->", cur->_data);
        cur = cur->_next;
    }
    printf("over\n");
}
//链表的长度
int ListSize(List* pcl)
{
    assert(pcl);
    ListNode* cur = pcl->_head->_next;
    int count = 0;
    //遍历一遍链表(不算头结点)
    while (cur != pcl->_head)
    {
        count++;
        cur = cur->_next;
    }
    return count;
}
//判断链表是否为空(为空返回0,非空返回1)
int ListEmpty(List* pcl)
{
    assert(pcl);
    //prev和next如果都指向自己,则链表为空
    return ((pcl->_head->_next == pcl->_head) && (pcl->_head->_prev == pcl->_head)) ? 0 : 1;
}
//寻找指定数据的结点(找到返回地址,找不到返回NULL)
ListNode* FindListNode(List* pcl, CLDataType x)
{
    assert(pcl);
    ListNode* cur = pcl->_head->_next;
    //遍历链表找到相同数据返回地址,找不到则返NULL
    while (cur != pcl->_head)
    {
        if (cur->_data == x)
        {
            return cur;
        }
        cur = cur->_next;
    }
    return NULL;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值