C语言实现单链表的初始化及增删改查

C语言实现单链表的初始化及增删改查
文件组织
在这里插入图片描述

main.c

//注意:linkList为头节点,头节点只是为了后面操作方便。其数据域无意义,但是头节点数据域通常保存链表长度,头指针指向第一个节点。
#include "test.h"

//初始化链表
void InitLinkList(LinkList * linkList,ElementType * dataArray,int length);
//插入节点
void InsertLinkList(LinkList * linkList,int pos,ElementType element);
//打印链表
void PrintLinkList(LinkList * linkList);
//判断链表是否为空
int IsLInkListEmpty(LinkList * linkList);
//删除并返回指定位置的节点
ElementType DeleteLinkListElement(LinkList * linkList,int pos);
//清空链表
void ClearLinkList(LinkList * linkList);

ElementType dataArray[] = {
    {1,"侠客行"},
    {2,"将进酒"},
    {3,"神来之笔"},
    {4,"青莲剑歌"}
};

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

void TestLinkList(){
    LinkList linkList;
    linkList.length = 0;//初始化链表长度为0
    InitLinkList(&linkList,dataArray,sizeof(dataArray)/sizeof(dataArray[0]));
    PrintLinkList(&linkList);

    //下面进行插入节点
    ElementType element;
    element.id = 5;
    element.name = (char *)malloc(8);  //一个汉字占2或3个字节
    //strcpy是一种C语言的标准库函数,strcpy把含有'\0'结束符的字符串复制到另一个地址空间,返回值的类型为char*。
    strcpy(element.name,"剑仙李白");
    InsertLinkList(&linkList,5,element);
    printf("插入新节点后:\n");
    PrintLinkList(&linkList);
    printf("是否为空?  %d\n",IsLInkListEmpty(&linkList));
    printf("删除第3个元素后:\n");
    DeleteLinkListElement(&linkList,3);
    PrintLinkList(&linkList);
    printf("清空链表后:\n");
    ClearLinkList(&linkList);
    PrintLinkList(&linkList);
}

test.c



#include "test.h"

//初始化链表
void InitLinkList(LinkList * linkList,ElementType * dataArray,int length)
{
    for (int i = 0;i<length;i++){
        InsertLinkList(linkList,i+1,dataArray[i]);   //注意:这里是在pos位置处插入,故从1开始计数.相反,若是index,则为0开始.
    }
}

//插入元素
void InsertLinkList(LinkList * linkList,int pos,ElementType element){
    //1.创建空节点并为数据域赋值
    //用malloc创建空节点空间,(Node *)强制类型转换为指向Node型的指针
    Node * node = (Node *)malloc(sizeof(Node));
    node->data = element;
    node->next = NULL;

    //2.找到插入位置的节点
    //如果插入位置为第一个
    //注意:linkList为头节点,头节点只是为了后面操作方便。其数据域无意义,但是头节点数据域通常保存链表长度,头指针指向第一个节点。
    if (pos == 1){
        linkList->next=node;
        linkList->length++;
        return;
    }
    //如果不是插入第一个
    Node * currNode = linkList->next;
    for (int i = 1;currNode && i<pos-1;i++){
        currNode = currNode->next;
    }
    if (currNode){
        node->next = currNode->next;
        currNode->next = node;
        linkList->length++;
    }
}


void PrintLinkList(LinkList * linkList){
    Node * currentNode = linkList->next;
    if (!currentNode){
        printf("LinkList is NULL.\n");
        linkList->length=0;
    }

    for(int i=0;i<linkList->length;i++){
        printf("%d技能  %s.\n",currentNode->data.id,currentNode->data.name);
        currentNode = currentNode->next;
    }
}

//.h中有宏定义,TRUE=1,FALSE=0
int IsLInkListEmpty(LinkList * linkList){
    return linkList->length == 0 ? TRUE : FALSE;
}


ElementType DeleteLinkListElement(LinkList * linkList,int pos){
    ElementType element;  //被删除的元素
    element.id=-99999;    //赋一个不可能的值,来判断是否删除成功
    Node * node = NULL;
    if (pos == 1){      //如果删除第一个节点
        node = linkList->next;  //头节点
        if (node){
            element = node->data;  //保存被删除的元素
            linkList->next = node->next;
            free(node);
            linkList->length--;
        }
        return element;
    }

    //如果不是删除第一个节点
    Node * preNode; //前缀节点
    node = linkList->next;
    for (int i=1;node && i<pos;i++){
        preNode = node;
        node = node->next;
    }
    if (node){
        element = node->data;
        preNode->next = node->next;
        free(node);
        linkList->length--;
    }
    return element;
}



//清空链表
void ClearLinkList(LinkList * linkList){
    Node * node = linkList->next;
    Node * nextNode;  //定义两个指针来删除链表

    while(node) {
        nextNode = node->next;      //先记录当前节点的下一个节点,以便释放当前节点的内存
        free(node);
        node = nextNode;
    }
    linkList->next = NULL;
    linkList->length = 0;
}

test.h

test.h


#ifndef TEST_H_INCLUDED
#define TEST_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
//定义节点的数据域ElementType
typedef struct {
    int id;
    char * name;
}ElementType;

//加上指针域,构成节点
typedef struct Node{
    ElementType data;
    struct Node * next;
}Node;

//定义名为LinkList的头节点!!
//注意:linkList为头节点,头节点只是为了后面操作方便。其数据域无意义,但是头节点数据域通常保存链表长度,头指针指向第一个节点。
typedef struct LinkList{
    Node * next;
    int length;
}LinkList;

#endif // TEST_H_INCLUDED

运行结果如下:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值