链表C语言

链表C语言

LinkList.h文件

#ifndef LINK_LIST_H
#define LINK_LIST_H

typedef unsigned char LElemType;  //元素的数据类型

/*结点的存储结构*/
typedef struct LinkNode 
{
    LElemType data;              //数据域
    struct LinkNode* next;       //指针域(存储后继结点)
}LinkNode;
/*链表要素*/
typedef struct 
{
    unsigned int Length;     //链表的长度
    LinkNode Head;           //头结点
    LinkNode* pTail;         //定义一个尾指针
}LinkList;

/*单链表初始化*/
void LinkList_Init(LinkList* L);
/*添加结点*/
void LinkList_Append(LinkList* L,LElemType e);
/*遍历结点*/
void LinkList_Traverse(LinkList L);
/*获取 i 位置元素*/
LElemType LinkList_GetElem(LinkList L, unsigned int i);
/*删除在位置 i 处的结点*/
LElemType LinkList_Delete(LinkList* L, unsigned int i);
/*在位置 i 插入结点*/
void LinkList_Insert(LinkList* L, unsigned int i, LElemType e);
/*销毁链表,删除所有结点(头结点除外)*/
void LinkList_Clear(LinkList* L);
/*测试*/
void LinkList_Test(void);

#endif // LINK_LIST_H

LinkList.c文件

#include "LinkList.h"

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

/*单链表初始化*/
void LinkList_Init(LinkList* L)
{
    L->Length = 0;
    L->Head.data = 0;
    L->Head.next = NULL;

    L->pTail = &L->Head;     //尾指针指向头结点

    L->pTail->data = 0;
    L->pTail->next = NULL;
}
/*添加结点,尾插法建表*/
void LinkList_Append(LinkList* L,LElemType e)
{
    /*新建结点*/
    LinkNode* NewNode = malloc(sizeof(LinkNode));
    if (NewNode != NULL)
    {
        NewNode->data = e;
        NewNode->next = NULL;

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

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

    LinkNode* p = L.Head.next;
    while (p != NULL)
    {
        printf("%c ", p->data);
        p = p->next;
    }
    printf("\n");
}
/*获取 i 位置元素, i从0开始*/
LElemType LinkList_GetElem(LinkList L, unsigned int i)
{
    assert(L.Head.next != NULL);   //链表不为空
    assert(i < L.Length);                    //下标不超过元素个数
    LinkNode* p = L.Head.next;
    unsigned int j = 0;
    while (p != NULL)
    {
        if (j == i)
            return p->data;

        p = p->next;
        j++;
    }
    return 0;
}

/*删除在位置 i 处的结点,i从0开始*/
LElemType LinkList_Delete(LinkList* L, unsigned int i)
{
    assert(L->Head.next != NULL);   //链表不为空
    assert(i < L->Length);          //下标不超过元素个数

    LinkNode* p = &L->Head;
    unsigned int j = 0;
    while (p->next != NULL)
    {
        if (i == j)
        {
            LElemType e = p->next->data;
            if (p->next == L->pTail)    //如果当前结点的后继等于尾指针
            { 
                L->pTail = p;           //尾指针前移
            }

            LinkNode* temp = p->next;   //记录当前结点的后继
            p->next = temp->next;       //当前结点的后继变为temp的后继
            free(temp);

            L->Length -= 1;
            return e;
        }
        p = p->next;
        j++;
    }
    return 0;
}

/*在位置 i 插入结点,i从0开始*/
void LinkList_Insert(LinkList* L, unsigned int i, LElemType e)
{
    assert(L->Head.next != NULL);   //链表不为空
    assert(i < L->Length);          //下标不超过元素个数

    LinkNode* p = &L->Head;
    unsigned int j = 0;
    while (p->next != NULL)
    {
        if (j == i)
        {
            LinkNode* NewNode = (LinkNode*)malloc(sizeof(LinkNode));
            if (NewNode != NULL)
            {
                NewNode->data = e;

                NewNode->next = p->next;  //新结点的后继等于p结点的后继
                p->next = NewNode;        //p结点的后继等于新结点

                L->Length += 1;
                break;
            }
            else
                printf("申请内存不足!");
        }
        p = p->next;
        j++;
    }
}

/*销毁链表,删除所有结点(头结点除外)*/
void LinkList_Clear(LinkList* L)
{
    assert(L->Head.next != NULL);   //链表不为空

    LinkNode* temp;
    while (L->Head.next != NULL)
    {
        temp = L->Head.next;
        L->Head.next = temp->next;
        free(temp);
    }
    L->pTail = &L->Head;
}

/*测试*/
void LinkList_Test(void)
{
    LinkList L;
    LinkList_Init(&L);
    LinkList_Append(&L,'A');
    LinkList_Append(&L,'B');
    LinkList_Append(&L,'C');
    LinkList_Append(&L,'D');
    LinkList_Traverse(L);
    printf("%c\n", LinkList_GetElem(L, 0));

    LinkList_Insert(&L, 3, 'Z');
    LinkList_Traverse(L);

    printf("%c\n", LinkList_Delete(&L, 0));
    LinkList_Traverse(L);

    LinkList_Append(&L,'E');
    LinkList_Traverse(L);
    LinkList_Clear(&L);
    LinkList_Traverse(L);
}

测试:main.c文件

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

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

测试结果:

LinkList.c

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

往昔的恒纳兰那

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

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

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

打赏作者

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

抵扣说明:

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

余额充值