数据结构-双向循环链表(增、删、改、查)

1.main.c

#include <stdio.h>
#include "doublecircllist.h"

int main()
{
    DoubleCircLList_t *doublecircllist;
    DataType_t num[] = {1, 2, 3, 4, 5, 6};
    DataType_t size  = ((sizeof(num)) / (sizeof(num[0])));

    // 创建双向循环链表
    doublecircllist = DoubleCircLList_Create();
    // 错误判断
    if (NULL == doublecircllist){
        printf("error!!!!!\n");
    }

     // 插入元素
    for (int i = 0; i < size; i++){
        if (0 != DoubleCircLList_TailInsert(doublecircllist, num[i])){
            printf("error!!!!!\n");
            printf("\n");
        }            
    }
    // 遍历元素
    printf("双向循环链表的元素(尾插):");
    DoubleCircLList_Show(doublecircllist);
    printf("\n");

    // 头部插入元素
    int n = 0;
    DoubleCircLList_HeadInsert(doublecircllist, n);
    // 遍历元素
    printf("头部双向循环链表元素:");
    DoubleCircLList_Show(doublecircllist);
    printf("\n");

    // 尾部插入元素
    int m = 7;
    DoubleCircLList_TailInsert(doublecircllist, m);
    // 遍历元素
    printf("尾部双向循环链表元素:");
    DoubleCircLList_Show(doublecircllist);
    printf("\n");

    
    // 指定位置插入元素
    int a = 8;
    int pos1 = 9;
    DoubleCircLList_OrderInsert(doublecircllist, a, pos1);
    // 遍历元素
    printf("指定位置[%d]插入双向循环链表元素:", pos1);
    DoubleCircLList_Show(doublecircllist);
    printf("\n");    
    
    // 头部删除元素
    if (0 != DoubleCircLList_HeadDelete(doublecircllist)){
        printf("error!!!!!\n");
        printf("\n");
    }
    else{
        // 遍历元素
        printf("头部删除双向循环链表元素:");
        DoubleCircLList_Show(doublecircllist);
        printf("\n");
    }

    // 尾部删除元素
    if (0 != DoubleCircLList_TailDelete(doublecircllist)){
        printf("error!!!!!\n");
        printf("\n");
    }
    else{
        // 遍历元素
        printf("尾部删除双向循环链表元素:");
        DoubleCircLList_Show(doublecircllist);
        printf("\n");
    }

    // 指定位置删除元素
    int pos2 = 7;
    if (0 != DoubleCircLList_OrderDelete(doublecircllist, pos2)){
        printf("error!!!!!\n");
        printf("\n");
    }
    else{
        // 遍历元素
        printf("指定位置[%d]删除双向循环链表元素:", pos2);
        DoubleCircLList_Show(doublecircllist);
        printf("\n");
    }

    // 查找元素
    int ele1 = 2;
    int ret = DoubleCircLList_Find(doublecircllist, ele1);
    if (0 == ret){
        printf("error!!!!!\n");
        printf("\n");
    }
    else{
        printf("查找元素[%d]在单向循环链表中的下标是:%d\n", ele1, ret);
        printf("\n");
    }

    // 修改元素
    int f_ele2 = 2;
    int c_ele3 = 3;
    DoubleCircLList_Change(doublecircllist, f_ele2, c_ele3);
    // 遍历元素
    printf("将链表元素[%d]修改为[%d]:", f_ele2, c_ele3);
    DoubleCircLList_Show(doublecircllist);
    printf("\n");

    // 释放双向循环链表的内存空间
    DoubleCircLList_Free(doublecircllist);

    return 0;
}

2.doublecircllist.c

#include "doublecircllist.h"

// 创建一个双向循环链表的头结点
DoubleCircLList_t *DoubleCircLList_Create()
{
    DoubleCircLList_t *doublecircllist;
    // 申请内存空间
    doublecircllist = (DoubleCircLList_t *)calloc(1, sizeof(DoubleCircLList_t));
    // 错误判断
    if (NULL == doublecircllist){
        return NULL;
    }
    // 头结点的直接前驱的指针域和直接后继的指针域指向自身,形成“循环”
    doublecircllist->prev = doublecircllist;
    doublecircllist->next = doublecircllist;

    // 返回头结点地址
    return doublecircllist;
}

// 双向循环链表插入元素(头部)
int DoubleCircLList_HeadInsert(DoubleCircLList_t *doublecircllist, DataType_t data)
{
    // 保存头结点地址
    DoubleCircLList_t *doublecircllist1 = doublecircllist;

    // 创建新节点
    DoubleCircLList_t *newdoublecircllist;
    // 申请内存空间
    newdoublecircllist = (DoubleCircLList_t *)calloc(1, sizeof(DoubleCircLList_t));
    // 错误判断
    if (NULL == newdoublecircllist){
        return -1;
    }
    newdoublecircllist->prev = newdoublecircllist;
    newdoublecircllist->next = newdoublecircllist;

    // 双向循环链表为空
    if (doublecircllist1 == doublecircllist1->next){
        // 将头结点的next指针域指向新结点
        doublecircllist1->next = newdoublecircllist;
        // 插入元素
        newdoublecircllist->data = data;
    }
    else{
        // 双向循环链表非空
        while (doublecircllist1->next){
            // 依次后向移动
            doublecircllist1 = doublecircllist1->next;
            // 找到最后一个结点
            if (doublecircllist->next == doublecircllist1->next){
                // 将新结点的next指针域指向首结点
                newdoublecircllist->next = doublecircllist->next;
                // 将新结点的prev指针域指向尾结点
                newdoublecircllist->prev = doublecircllist1;
                // 将尾结点的next指针域指向新结点
                doublecircllist1->next = newdoublecircllist;
                // 将头结点的next指针域指向新结点
                doublecircllist->next = newdoublecircllist;
                // 插入元素
                newdoublecircllist->data = data;
                break;
            }
        }
    }

    return 0;
}

// 双向循环链表插入元素(尾部)
int DoubleCircLList_TailInsert(DoubleCircLList_t *doublecircllist, DataType_t data)
{
    // 保存头结点地址
    DoubleCircLList_t *doublecircllist1 = doublecircllist;

    // 创建新节点
    DoubleCircLList_t *newdoublecircllist;
    // 申请内存空间
    newdoublecircllist = (DoubleCircLList_t *)calloc(1, sizeof(DoubleCircLList_t));
    // 错误判断
    if (NULL == newdoublecircllist){
        return -1;
    }
    newdoublecircllist->prev = newdoublecircllist;
    newdoublecircllist->next = newdoublecircllist;

    // 双向循环链表为空
    if (doublecircllist1 == doublecircllist1->next){
        // 将头结点的next指针域指向新结点
        doublecircllist1->next = newdoublecircllist;
        // 插入元素
        newdoublecircllist->data = data;
    }
    else{
        // 双向循环链表非空
        while (doublecircllist1->next){
            // 依次后向移动
            doublecircllist1 = doublecircllist1->next;
            // 找到最后一个结点
            if (doublecircllist->next == doublecircllist1->next){
                // 将新结点的next指针域指向首结点
                newdoublecircllist->next = doublecircllist->next;
                // 将新结点的prev指针域指向尾结点
                newdoublecircllist->prev = doublecircllist1;
                // 将尾结点的next指针域指向新结点
                doublecircllist1->next = newdoublecircllist;
                // 将首结点的prev指针域指向新结点
                doublecircllist->next->prev = newdoublecircllist;
                // 插入元素
                newdoublecircllist->data = data;
                break;
            }
        }
    }

    return 0;
}

// 插入双向循环链表元素(指定位置)
int DoubleCircLList_OrderInsert(DoubleCircLList_t *doublecircllist, DataType_t data, int pos)
{
    int i = 0;
    DoubleCircLList_t *doublecircllist1 = doublecircllist;
    pos -= 1;

    // 创建新节点
    DoubleCircLList_t *newdoublecircllist;
    // 申请内存空间
    newdoublecircllist = (DoubleCircLList_t *)calloc(1, sizeof(DoubleCircLList_t));
    // 错误判断
    if (NULL == newdoublecircllist){
        return -1;
    }
    newdoublecircllist->prev = newdoublecircllist;
    newdoublecircllist->next = newdoublecircllist;

    // 双向循环链表为空
    if (doublecircllist1 == doublecircllist1->next){
        // 将头结点的next指针域指向新结点
        doublecircllist1->next = newdoublecircllist;
        // 插入元素
        newdoublecircllist->data = data;
    }
    else{
        // 双向循环链表非空
        while (doublecircllist1->next){
            // 结点依次向后移动,找到双向循环链表的指定位置
            doublecircllist1 = doublecircllist1->next;
            i++;
            // 找到双向循环链表中的最后一个结点
            if (doublecircllist->next == doublecircllist1->next){
                // 双向循环链表中的最后一个结点的指针域指向新节点的地址
                doublecircllist1->next = newdoublecircllist;
                // 新结点的prev指针域指向尾结点的地址
                newdoublecircllist->prev = doublecircllist1;  
                // 新结点的next指针域指向首结点的地址  
                newdoublecircllist->next = doublecircllist->next;
                // 插入元素
                newdoublecircllist->data = data;
                // 跳出循环
                break;
            }
            // 找到指定位置-(要删除结点的前一个结点)
            if (pos == i){            
                // 插入元素
                newdoublecircllist->data = data;
                // 将新结点的next指针域指向当前结点的下一个结点的地址
                newdoublecircllist->next = doublecircllist1->next;                
                // 将新结点的prev指针域指向当前结点的地址
                newdoublecircllist->prev = doublecircllist1;
                // 当前结点的下一个结点的prev指针域指向新结点的地址
                doublecircllist1->next->prev = newdoublecircllist;
                // 当前结点的指针域指向新结点的地址
                doublecircllist1->next = newdoublecircllist;
                break;
            }
        }   
    }

    return 0;
}

// 删除双向循环链表元素(头删)
int DoubleCircLList_HeadDelete(DoubleCircLList_t *doublecircllist)
{
    // 头节点地址
    DoubleCircLList_t *doublecircllist1 = doublecircllist;
    // 首结点地址
    DoubleCircLList_t *doublecircllist2 = doublecircllist->next;

    // 双向循环链表为空
    if (doublecircllist == doublecircllist->next){
        perror("the circular linkedlist is empty!!!!!\n");
        return -1;
    }

    // 单向循环链表中只有首结点
    if (doublecircllist2 == doublecircllist2->next){
        // 将头节点指向自己
        doublecircllist->next = doublecircllist;        
        // 将首结点的prev指针域指向NULL
        doublecircllist2->prev = NULL;
        // 将首结点的next指针域指向NULL
        doublecircllist2->next = NULL;
        // 释放首结点地址
        free(doublecircllist2);
        doublecircllist2 = NULL;
    }
    else{
        while (doublecircllist1->next){
            // 依次向后移动结点
            doublecircllist1 = doublecircllist1->next;      // 更新为首结点地址
            // 找到最后一个结点
            if (doublecircllist->next == doublecircllist1->next){
                // 尾结点的next指针域指向首结点的下一个结点的地址
                doublecircllist1->next = doublecircllist2->next;
                // 头结点的next指针域指向首结点的下一个结点的地址
                doublecircllist->next = doublecircllist2->next;
                // 将首结点的next指针域指向NULL
                doublecircllist2->next = NULL;
                // 释放首结点的内存空间
                free(doublecircllist2);
                doublecircllist2 = NULL;
                // 跳出循环
                break;
            }
        }
    }

    return 0;
}

// 删除双向循环链表元素(尾删)
int DoubleCircLList_TailDelete(DoubleCircLList_t *doublecircllist)
{
    // 头节点地址
    DoubleCircLList_t *doublecircllist1 = doublecircllist;
    // 首结点地址
    DoubleCircLList_t *doublecircllist2 = doublecircllist->next;

    // 双向循环链表为空
    if (doublecircllist == doublecircllist->next){
        perror("the circular linkedlist is empty!!!!!\n");
        return -1;
    }

    // 单向循环链表中只有首结点
    if (doublecircllist2 == doublecircllist2->next){
        // 将头节点指向自己
        doublecircllist->next = doublecircllist;        
        // 首结点的prev指针域指向NULL
        doublecircllist2->prev = NULL;
        // 首结点的next指针域指向NULL
        doublecircllist2->next = NULL;
        // 释放首结点地址
        free(doublecircllist2);
        doublecircllist2 = NULL;
    }
    else{
        while (doublecircllist1->next){
            // 依次向后移动结点
            doublecircllist1 = doublecircllist1->next;
            // 找到最后一个结点
            if (doublecircllist->next == doublecircllist1->next){
                // 尾结点的前一个结点的next指针域指向首结点地址
                doublecircllist1->prev->next = doublecircllist2;
                // 首结点的prev指针域指向尾结点的前一个结点的地址
                doublecircllist2->prev = doublecircllist1->prev;
                // 尾结点的prev指针域指向NULL
                doublecircllist1->prev = NULL;
                // 尾结点的next指针域指向NULL
                doublecircllist1->next = NULL;
                // 释放尾结点的内存空间
                free(doublecircllist1);
                doublecircllist1 = NULL;
                break;
            }
        }
    }

    return 0;
}

// 删除双向循环链表元素(指定位置删)
int DoubleCircLList_OrderDelete(DoubleCircLList_t *doublecircllist, int pos)
{
    int i = 0;
    // 头节点地址
    DoubleCircLList_t *doublecircllist1 = doublecircllist;
    // 首结点地址
    DoubleCircLList_t *doublecircllist2 = doublecircllist->next;
    DoubleCircLList_t *doublecircllist3 = NULL;
    pos -= 1;

    // 单向循环链表为空
    if (doublecircllist == doublecircllist->next){
        perror("the circular linkedlist is empty!!!!!\n");
        return -1;
    }

    // 单向循环链表中只有首结点
    if (doublecircllist2 == doublecircllist2->next){
        // 将头节点指向自己
        doublecircllist->next = doublecircllist;        
        // 将首结点的prev指针域指向NULL
        doublecircllist2->prev = NULL;
        // 将首结点的next指针域指向NULL
        doublecircllist2->next = NULL;
        // 释放首结点地址
        free(doublecircllist2);
        doublecircllist2 = NULL;
    }
    else{
        while (doublecircllist1->next){
            // 依次向后移动结点
            doublecircllist1 = doublecircllist1->next;      // 更新为首结点地址
            // 找到最后一个结点
            if (doublecircllist->next == doublecircllist1->next){
                // 尾结点的前一个结点的next指针域指向首结点地址
                doublecircllist1->prev->next = doublecircllist2;
                // 首结点的prev指针域指向尾结点的前一个结点的地址
                doublecircllist2->prev = doublecircllist1->prev;
                // 尾结点的prev指针域指向NULL
                doublecircllist1->prev = NULL;
                // 尾结点的next指针域指向NULL
                doublecircllist1->next = NULL;
                // 释放尾结点的内存空间
                free(doublecircllist1);
                doublecircllist1 = NULL;
                break;
            }
            i++;
            // 找到指定位置-(要删除结点的前一个结点)
            if (pos == i){
                // 将指定删除的结点的地址保存在 circllist3
                doublecircllist3 = doublecircllist1->next;
                // 将当前结点的next指针域指向要删除的结点的下一个结点的地址
                doublecircllist1->next = doublecircllist3->next;
                // 将要删除结点的下一个结点的prev指针域指向的当前结点的地址
                doublecircllist3->next->prev = doublecircllist1;
                // 将要删除的结点的prev指针域指向NULL
                doublecircllist3->prev = NULL;
                // 将要删除的结点的next指针域指向NULL
                doublecircllist3->next = NULL;
                // 释放要删除的结点的内存空间
                free(doublecircllist3);
                doublecircllist3 = NULL;
                break;
            }
        }
    }

    return 0;
}

// 查找元素
int DoubleCircLList_Find(DoubleCircLList_t *doublecircllist, DataType_t data)
{
    int pos = 0;
    DoubleCircLList_t *doublecircllist1 = doublecircllist;

    // 单向循环链表为空
    if (doublecircllist == doublecircllist->next){
        perror("the circular linkedlist is empty!!!!!\n");
        return 0;
    }

    while (doublecircllist1->next){
        // 依次向后移动一个结点
        doublecircllist1 = doublecircllist1->next;       
        // 找到该元素
        if (data == doublecircllist1->data){
            break;
        }
        // 找到最后一个结点没有找到该元素
        if (doublecircllist->next == doublecircllist1->next){
            perror("the element is not find!!!!!\n");
            break;
        }        
        // 计数器的值加1
        pos++; 
    }
    pos += 1;

    return pos;
} 

// 修改元素
int DoubleCircLList_Change(DoubleCircLList_t *doublecircllist, DataType_t data, DataType_t changenum)
{
     DoubleCircLList_t *doublecircllist1 = doublecircllist;

    // 单向循环链表为空
    if (doublecircllist == doublecircllist->next){
        perror("the circular linkedlist is empty!!!!!\n");
        return 0;
    }

    while (doublecircllist1->next){
        // 依次向后移动一个结点
        doublecircllist1 = doublecircllist1->next;       
        // 找到该元素
        if (data == doublecircllist1->data){
            doublecircllist1->data = changenum;
            break;
        }
        // 找到最后一个结点没有找到该元素
        if (doublecircllist->next == doublecircllist1->next){
            perror("the element is not find!!!!!\n");
            break;
        }
    }

    return 0;
} 

// 遍历双向循环链表中的元素
void DoubleCircLList_Show(DoubleCircLList_t *doublecircllist)
{
    // 保存头结点地址
    DoubleCircLList_t *doublecircllist1 = doublecircllist;
    // 判断双向循环链表是否为空
    if (doublecircllist1 == doublecircllist1->next){
        return ;
    }    
    // 依次后向移动
    while (doublecircllist1->next){
        doublecircllist1 = doublecircllist1->next;
        printf("%d ", doublecircllist1->data);
        if (doublecircllist->next == doublecircllist1->next){
            break;
        }
    }

    printf("\n");
}

// 释放双向循环链表的内存空间
void DoubleCircLList_Free(DoubleCircLList_t *doublecircllist)
{
    DoubleCircLList_t *doublecircllist1 = NULL;
    DoubleCircLList_t *doublecircllist2 = NULL;

    for (doublecircllist1 = doublecircllist->next; doublecircllist->next != doublecircllist1; doublecircllist1 = doublecircllist2){
        // 依次向后移动
        doublecircllist1 = doublecircllist1->next;              // 第一次赋值的是首结点的下一个结点的地址
        // 将当前节点的下一个结点的地址保存在doublecircllist2
        doublecircllist2 = doublecircllist1->next;              // 首结点的下一个结点的下一个结点的地址
        //释放内存空间
        free(doublecircllist1);                                 // 是从首结点的下一个结点的地址开始释放内存空间
    }
    // 释放首结点的内存空间
    free(doublecircllist->next);
    // 释放头结点的内存空间
    free(doublecircllist);
    doublecircllist1 = NULL;
    doublecircllist2 = NULL;
}

3.doublecircllist.h

#ifndef _DOUBLECIRLINKEDLIST_H_
#define _DOUBLECIRLINKEDLIST_H_

#include <stdio.h>
#include <stdlib.h>

typedef int DataType_t;

typedef struct DoubleCircLList{
    DataType_t data;
    struct DoubleCircLList *prev;   // 直接前驱的指针域
    struct DoubleCircLList *next;   // 直接后继的指针域
}DoubleCircLList_t;

DoubleCircLList_t *DoubleCircLList_Create();
int DoubleCircLList_HeadInsert(DoubleCircLList_t *doublecircllist, DataType_t data);
int DoubleCircLList_TailInsert(DoubleCircLList_t *doublecircllist, DataType_t data);
int DoubleCircLList_OrderInsert(DoubleCircLList_t *doublecircllist, DataType_t data, int pos);
int DoubleCircLList_HeadDelete(DoubleCircLList_t *doublecircllist);
int DoubleCircLList_TailDelete(DoubleCircLList_t *doublecircllist);
int DoubleCircLList_OrderDelete(DoubleCircLList_t *doublecircllist, int pos);
int DoubleCircLList_Find(DoubleCircLList_t *doublecircllist, DataType_t data);
int DoubleCircLList_Change(DoubleCircLList_t *doublecircllist, DataType_t data, DataType_t changenum);
void DoubleCircLList_Show(DoubleCircLList_t *doublecircllist);
void DoubleCircLList_Free(DoubleCircLList_t *doublecircllist);

#endif

4.运行结果

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值