实现循环双链表各种基本运算的算法

本文介绍了一个使用C语言实现的循环双链表的基本操作,包括初始化、插入、删除等,并通过一个完整的示例展示了这些操作的具体应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
*    实验题目:
*        实现循环双链表各种基本运算的算法
*    实验内容:
*        编写一个程序实现循环双链表的各种基本运算,并在此基础上设计一个主程序
*    完成如下功能:
*    (1)初始化循环双链表h
*    (2)依次采用尾部插入法插入a,b,c,d,e元素
*    (3)输出循环双链表h
*    (4)输出循环双链表h长度
*    (5)判断循环双链表h是否为空
*    (6)输出循环双链表h的第3个元素
*    (7)输出元素a的位置
*    (8)在第4个元素位置上插入f元素
*    (9)输出循环双链表h
*    (10)删除h的第3个元素
*    (11)输出循环双链表h
*    (12)释放循环双链表h
*/

#include <stdio.h>
#include <malloc.h>

typedef char ElemType;
typedef struct DNode                        // 定义循环双链表结点类型
{
    ElemType data;                            // 数据域
    struct DNode *prior;                    // 指向直接前驱结点
    struct DNode *next;                        // 指向直接后继结点
}DLinkList;


/*-------------------------初始化循环双链表L----------------------------*/
void InitList(DLinkList *&L)    // 指针的引用
{
    L = (DLinkList *)malloc(sizeof(DLinkList));            // 创建头结点
    L->prior = L->next = L;
}

/*-------------------------释放循环双链表L----------------------------*/
void DestroyList(DLinkList *&L)
{
    DLinkList *p = L;
    DLinkList *q = p->next;
    
    while(q != L)
    {
        free(p);
        p = q;
        q = p->next;
    }
    free(p);
}

/*-------------------------判断循环双链表L是否为空表----------------------------*/
int ListEmpty(DLinkList *L)
{
    return (L->next == L);
}

/*-------------------------返回循环双链表L的元素个数----------------------------*/
int ListLength(DLinkList *L)
{
    int i = 0;
    DLinkList *p = L;
    
    while(p->next != L)
    {
        i++;
        p = p->next;
    }
    return i;
}

/*-------------------------输出循环双链表L----------------------------*/
void DispList(DLinkList *L)
{
    DLinkList *p = L->next;
    
    while(p != L)
    {
        printf("%c ", p->data);
        p = p->next;
    }
    printf("\n");
}

/*-------------------------获取循环双链表L中第i个元素----------------------------*/
int GetElem(DLinkList *L, int i, ElemType &e)
{
    int j = 0;
    DLinkList *p;
    
    if(L->next != L)                                // 循环双链表为非空表时
    {
        if(i == 1)
        {
            e = L->next->data;                        // 提取元素
            return 1;
        }
        else                                        // i不为1时
        {
            p = L->next;
            while((p != L) && (j < i - 1))            
            {
                j++;
                p = p->next;
            }
            if(p == L)
                return 0;
            else
            {
                e = p->data;
                return 1;
            }
        }
    }
    else                                            // 循环双链表为空表时
        return 0;
}

/*-------------------------在循环双链表L中查找元素e----------------------------*/
int LocateElem(DLinkList *L, ElemType e)
{
    int n = 1;
    DLinkList *p = L->next;
    
    while((p != L) && (p->data != e))
    {
        n++;
        p = p->next;
    }
    if(p == NULL)
        return 0;
    else
        return n;
}

/*-------------------------在循环双链表L中第i个位置上插入元素e----------------------------*/
int ListInsert(DLinkList *&L, int i, ElemType e)
{
    int j = 0;
    DLinkList *p = L, *s;
    
    if(p->next == L)                                    // 原双链表为空表时
    {
        s = (DLinkList *)malloc(sizeof(DLinkList));        // 创建新结点s
        s->data = e;
        p->next = s; s->next = p;
        p->prior = s; s->prior = p;
        return 1;
    }
    else if(i == 1)                                        // 原双链表不为空表但i=1时
    {
        s = (DLinkList *)malloc(sizeof(DLinkList));        // 创建新结点s
        s->data = e;
        // 将s插入到结点p之后
        s->next = p->next;
        p->next = s;
        s->next->prior = s;
        s->prior = p;
        return 1;
    }
    else
    {
        p = L->next;
        while((p != L) && (j < i - 2))
        {
            j++;
            p = p->next;
        }
        if(p == L)                                        // 未找到第i-1个结点
            return 0;
        else                                            // 找到第i-1个结点p
        {
            s = (DLinkList *)malloc(sizeof(DLinkList));    // 创建新结点s
            s->data = e;
            // 将s插入到结点p之后
            s->next = p->next;
            if(p ->next != NULL)
                p->next->prior = s;
            s->prior = p;
            p->next = s;
            return 1;
        }
    }
}

/*-------------------------在循环双链表L中删除第i个元素e----------------------------*/
int ListDelete(DLinkList *&L, int i, ElemType &e)
{
    int j = 0;
    DLinkList *p = L, *q;
    
    if(p->next != L)                                    // 原双链表不为空表时
    {
        if(i == 1)                                        // i=1时
        {
            q = L->next;                                // 删除第1个结点
            e = q->data;
            L->next = q->next;
            q->next->prior = L;
            free(q);
            return 1;
        }
        else                                            // i不为1时
        {
            p = L->next;
            while((p != NULL) && (j < i - 2))
            {
                j++;
                p = p->next;
            }
            if(p == NULL)                                // 未找到第i-1个结点
                return 0;
            else                                        // 找到第i-1个结点p
            {
                q = p->next;                            // q指向要删除的结点
                if(q == NULL)                            // 不存在第i个结点
                    return 0;
                e = q->data;
                // 从链表中删除q结点
                p->next = q->next;
                if(p->next != NULL)
                    p->next->prior = p;
                free(q);
                return 1;
            }
        }
    }
    else                                                // 原双链表为空表时
        return 0;
}

int main(void)
{
    DLinkList *h;
    ElemType e;
    
    printf("(1)初始化循环双链表h\n");
    InitList(h);
    printf("(2)依次采用尾插入法插入a,b,c,d,e元素\n");
    ListInsert(h, 1, 'a');
    ListInsert(h, 2, 'b');
    ListInsert(h, 3, 'c');
    ListInsert(h, 4, 'd');
    ListInsert(h, 5, 'e');
    printf("(3)输出循环双链表h:");
    DispList(h);
    printf("(4)循环双链表h长度=%d\n", ListLength(h));
    printf("(5)循环双链表h为%s\n", (ListEmpty(h) ? "空" : "非空"));
    GetElem(h, 3, e);
    printf("(6)循环双链表h的第3个元素=%c\n", e);
    printf("(7)元素a的位置=%d\n", LocateElem(h, 'a'));
    printf("(8)在第4个元素位置上插入f元素\n");
    ListInsert(h, 4, 'f');
    printf("(9)输出循环双链表h:");
    DispList(h);
    printf("(10)删除h的第3个元素\n");
    ListDelete(h, 3, e);
    printf("(11)输出循环双链表h:");
    DispList(h);
    printf("(12)释放循环双链表h\n");
    DestroyList(h);

    return 0;
}

测试结果:

(1)初始化循环双链表h
(2)依次采用尾插入法插入a,b,c,d,e元素
(3)输出循环双链表h:a b c d e
(4)循环双链表h长度=5
(5)循环双链表h为非空
(6)循环双链表h的第3个元素=c
(7)元素a的位置=1
(8)在第4个元素位置上插入f元素
(9)输出循环双链表h:a b c f d e
(10)删除h的第3个元素
(11)输出循环双链表h:a b f d e
(12)释放循环双链表h

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值