双向链表C语言

双向链表C语言描述

DuLinkList.h

#ifndef DULINKLIST_H
#define DULINKLIST_H

typedef unsigned char DuLElemType;

typedef struct DuLinkNode
{
	DuLElemType data;          //数据
	struct DuLinkNode* prior;  //前驱
	struct DuLinkNode* next;   //后继
} DuLinkNode;

typedef struct
{
	DuLinkNode Head;             //定义一个头结点
	DuLinkNode* pTail;           //定义一个尾指针
	 int Length;                 //链表长度
}DuLinkList;

/*双向链表初始化,创建头结点*/
void DuLinkList_Init(DuLinkList* L);
/*添加结点*/
void DuLinkList_Append(DuLinkList* L,DuLElemType e);
/*正向遍历链表*/
void DuLinkList_Traverse(DuLinkList L);
/*反向遍历链表*/
void DuLinkList_ReTraverse(DuLinkList L);
/*获取 i 位置元素*/
DuLElemType DuLinkList_GetElem(DuLinkList L, int i);
/*删除在位置 i 处的结点*/
DuLElemType DuLinkList_Delete( DuLinkList* L, int i);
/*在位置 i 的后面插入结点*/
void DuLinkList_Insert(DuLinkList* L, int i, DuLElemType e);
/*销毁链表,删除所有结点(头结点除外)*/
void DuDuLinkList_Clear(DuLinkList* L);
/*测试*/
void DuLinkList_Test(void);

#endif // !DULINKLIST_H

DuLinkList.c

#include "DuLinkList.h"

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

/*双向链表初始化,创建头结点*/
void DuLinkList_Init(DuLinkList* L)
{
    L->Head.data = 0;
    L->Head.prior = NULL;
    L->Head.next = NULL;

    L->pTail = &L->Head;  //尾指针指向头结点
    L->pTail->data = 0;
    L->pTail->prior = NULL;
    L->pTail->next = NULL;

    L->Length = 0;
}
/*添加结点,尾插结点*/
void DuLinkList_Append(DuLinkList* L,DuLElemType e)
{
    /*新建结点*/
    DuLinkNode* NewNode = malloc(sizeof(DuLinkNode));
    if (NewNode != NULL)
    {
        NewNode->data = e;
        NewNode->next = NULL;
        NewNode->prior = L->pTail;       //新结点的前驱等于之前的尾结点

        L->pTail->next = NewNode;        //新结点先是成为尾指针的后继
        L->pTail = NewNode;              //新结点再成为尾结点

        L->Length += 1;
    }
    else
        printf("申请内存失败!");
}
/*正向遍历链表*/
void DuLinkList_Traverse(DuLinkList  L)
{
    assert(L.Head.next != NULL);   //链表不为空

    DuLinkNode* p = L.Head.next;
    while (p != NULL)
    {
        printf("%c ", p->data);
        p = p->next;
    }
    printf("\n");
}
/*反向遍历链表*/
void DuLinkList_ReTraverse(DuLinkList L)
{
    assert(L.Head.next != NULL);   //链表不为空

    DuLinkNode* p = L.pTail;
    while (p != NULL)
    {
        printf("%c ", p->data);
        p = p->prior;
    }
    printf("\n");
}
/*获取 i 位置元素,i从0或-1开始;
从0开始为正向遍历,从-1开始为反向遍历*/
DuLElemType DuLinkList_GetElem(DuLinkList L,int i)
{
    assert(L.Head.next != NULL);   //链表不为空

    int j;
    DuLinkNode* p;
    if (i >= 0)
    {
        assert(i < L.Length);     //下标不超过元素个数
        p = L.Head.next;
        j = 0;
    }
    else
    {
        assert(i >= -L.Length);   //下标不超过元素个数
        p = L.pTail;
        j = -1;
    }
    while (p != NULL)
    {
        if (i == j)
            return p->data;
        if (i >= 0)
        {
            p = p->next;
            j++;
        }
        else
        {
            p = p->prior;
            j--;
        }
    }
    return 0;
}
/*删除在位置 i 处的结点,i从0或-1开始;
从0开始为正向遍历,从-1开始为反向遍历*/
DuLElemType DuLinkList_Delete(DuLinkList* L,  int i)
{
    assert(L->Head.next != NULL);   //链表不为空

    DuLinkNode* p;
    unsigned int j;
    if (i >= 0)
    {
        assert(i < L->Length);      //下标不超过元素个数
        p = L->Head.next;
        j = 0;
    }
    else
    {
        assert(i >= -L->Length);    //下标不超过元素个数
        p = L->pTail;
        j = -1;
    }

    while (p != NULL)
    {
        if (i == j)
        {
            DuLElemType e = p->data;

            DuLinkNode* temp = p;        //记录当前结点的后继
            if (p == L->pTail)           //如果当前结点等于尾指针
            {
                L->pTail = p->prior;     //尾指针前移
            }
            else
            {
                temp->next->prior = temp->prior; //temp后继的前驱变为temp的前驱
            }
            temp->prior->next = temp->next;      //temp前驱的后继等于temp的后继
            free(temp);

            L->Length -= 1;
            return e;
        }
        if (i >= 0)
        {
            p = p->next;
            j++;
        }
        else
        {
            p = p->prior;
            j--;
        }
    }
    return 0;
}
/*在位置 i 插入结点,i从0或-1开始;
从0开始为正向遍历,从-1开始为反向遍历*/
void DuLinkList_Insert(DuLinkList* L, int i, DuLElemType e)
{
    assert(L->Head.next != NULL);   //链表不为空
    DuLinkNode* p;
    unsigned int j;
    if (i >= 0)
    {
        assert(i < L->Length);     //下标不超过元素个数
        p = L->Head.next;
        j = 0;
    }
    else
    {
        assert(i >= -L->Length);   //下标不超过元素个数
        p = L->pTail;
        j = -1;
    }
    while (p != NULL)
    {
        if (j == i)
        {
            DuLinkNode* NewNode = malloc(sizeof(DuLinkNode));
            if (NewNode != NULL)
            {
                NewNode->data = e;
                
                NewNode->prior = p->prior;   //新结点的前驱等于p结点的前驱
                NewNode->next = p;           //新结点的后继等于p结点
                p->prior->next = NewNode;    //p结点前驱的后继等于新结点
                p->prior = NewNode;          //p结点的前驱等于新结点

                L->Length += 1;
                break;
            }
            else
                printf("申请内存不足!");
        }
        if (i >= 0)
        {
            p = p->next;
            j++;
        }
        else
        {
            p = p->prior;
            j--;
        }
    }
}
/*销毁链表,删除所有结点(头结点除外)*/
void DuDuLinkList_Clear(DuLinkList* L)
{
    assert(L->Head.next != NULL);   //链表不为空

    DuLinkNode* temp;
    while (L->Head.next != NULL)
    {
        temp = L->Head.next;
        L->Head.next = temp->next;
        free(temp);
    }
    L->pTail = &L->Head;
}
/*测试*/
void DuLinkList_Test(void)
{
    DuLinkList L;
    DuLinkList_Init(&L);
    DuLinkList_Append(&L,'A');
    DuLinkList_Append(&L, 'B');
    DuLinkList_Append(&L, 'C');
    DuLinkList_Append(&L, 'D');
    DuLinkList_Traverse(L);
    DuLinkList_ReTraverse(L);
   DuLinkList_Insert(&L, -4, 'b');
    DuLinkList_Traverse(L);
    DuLinkList_ReTraverse(L);
    printf("%c\n", DuLinkList_GetElem(L,-5));
    printf("%c\n", DuLinkList_Delete(&L, -5));
    DuLinkList_Append(&L, 'E');
    DuLinkList_Traverse(L);
    DuLinkList_ReTraverse(L);
    DuDuLinkList_Clear(&L);
    DuLinkList_Traverse(L);
}

测试:main.c文件

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

int main()
{
 	DuLinkList_Test();
	return 0;
}

测试结果:

DuLinkList_Test

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

往昔的恒纳兰那

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

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

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

打赏作者

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

抵扣说明:

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

余额充值