• 数据结构 线性链表


    //线性链表头文件
    #ifndef _vzhanglinklist
    #define _vzhanglinklist
    
    typedef struct _LinkNode{
        struct _LinkNode *pnext;
    }LinkNode;
    
    typedef void LinkList;
    
    //创建线性链表
    _declspec(dllexport)
    LinkList* LinkList_Create();
    
    //销毁线性链表
    _declspec(dllexport)
    int LinkList_Destroy(LinkList** list);
    
    //清空线性链表
    _declspec(dllexport)
    int LinkList_Clear(LinkList* list);
    
    //获取线性链表长度
    _declspec(dllexport)
    int LinkList_Length(LinkList* list);
    
    //线性链表指定位置插入元素
    _declspec(dllexport)
    int LinkList_Insert(LinkList* list, LinkNode* node, int pos);
    
    //获取线性链表指定位置的元素
    _declspec(dllexport)
    LinkNode* LinkList_Get(LinkList* list, int pos);
    
    //删除线性链表指定位置的元素
    _declspec(dllexport)
    LinkNode* LinkList_Delete(LinkList* list, int pos);
    
    #endif;
    //线性链表代码实现
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include"LinkList.h"
    
    /*
    强调:①链表中不提供对元素的删除功能,因为链表无法知道元素的大小
    ②MyLinkList结构体应该定义在方法实现的文件中,不要定义在.h文件里
    因为用户不需要知道MyLinkList结构体是怎么实现的
    */
    
    //定义链表对象
    typedef struct _MyLinkList{
        //定义链表头结点
        LinkNode head;
        //定义链表元素个数
        int length;
    }MyLinkList;
    
    //创建线性链表
    _declspec(dllexport)
    LinkList* LinkList_Create(){
        //创建链表结构
        MyLinkList *mylist = (MyLinkList *)malloc(sizeof(MyLinkList));
        if (mylist==NULL)
        {
            printf("创建链表分配内存失败!
    ");
            return NULL;
        }
        mylist->head.pnext= NULL;
        mylist->length = 0;
        return (LinkList*)mylist;
    }
    
    //销毁线性链表
    _declspec(dllexport)
    int LinkList_Destroy(LinkList** list){
        int ERRO_MSG = 0;
        if (list == NULL)
        {
            ERRO_MSG = -1;
            printf("list==NULL 传入参数不可以为空! erro msg:%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        MyLinkList * mylist = (MyLinkList *)*list;
        if (mylist!=NULL)
        {
            //链表的数据必须由用户删除
            free(mylist);
            mylist = NULL;
            *list = NULL;
        }
        return ERRO_MSG;
    }
    
    //清空线性链表
    _declspec(dllexport)
    int LinkList_Clear(LinkList* list){
        int ERRO_MSG = 0;
        if (list == NULL)
        {
            ERRO_MSG = -1;
            printf("list==NULL 传入参数不可以为空! erro msg:%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        MyLinkList * mylist = (MyLinkList *)list;
        mylist->head.pnext = NULL;
        mylist->length = 0;
        return ERRO_MSG;
    }
    
    //获取线性链表长度
    _declspec(dllexport)
    int LinkList_Length(LinkList* list){
        int ERRO_MSG = 0;
        if (list == NULL)
        {
            ERRO_MSG = -1;
            printf("list==NULL 传入参数不可以为空! erro msg:%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        MyLinkList * mylist = (MyLinkList *)list;
        return mylist->length;
    }
    
    //线性链表指定位置插入元素
    _declspec(dllexport)
    int LinkList_Insert(LinkList* list, LinkNode* node, int pos){
        int ERRO_MSG = 0,i=0;
        if (list == NULL)
        {
            ERRO_MSG = -1;
            printf("list==NULL 传入参数不可以为空! erro msg:%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        MyLinkList * mylist = (MyLinkList *)list;
        //此时current指针指向头结点  不指向第0个元素
        LinkNode * current = &mylist->head;
        for (i = 0; i < pos&&(current->pnext!=NULL); i++)
        {
            /*
            current->pnext!=NULL这个判断不能缺少  这是为了链表元素的连续  
            也是为了current->pnext指针操作不报错
            */
            current = current->pnext;
        }
        /*
        当在第0个位置插入  正好current此时是头结点  所以没问题
        */
        node->pnext = current->pnext;
        current->pnext = node;
        //元素个数+1
        mylist->length++;
        return ERRO_MSG;
    }
    
    //获取线性链表指定位置的元素
    _declspec(dllexport)
    LinkNode* LinkList_Get(LinkList* list, int pos){
        int ERRO_MSG = 0, i = 0;
        if (list == NULL)
        {
            ERRO_MSG = -1;
            printf("list==NULL 传入参数不可以为空! erro msg:%d
    ", ERRO_MSG);
            return NULL;
        }
        MyLinkList * mylist = (MyLinkList *)list;
        //判断获取元素的位置
        if (pos<0 || pos>mylist->length)
        {
            ERRO_MSG = -2;
            printf("该位置上没有元素! erro msg:%d
    ", ERRO_MSG);
            return NULL;
        }
        //
        /*
        注意:此时跟插入方法有区别
        插入方法中,current指向的是头结点,在本方法中current指向的是第0个元素
        这是为了 获取第0个位置的元素 方便
        */
        LinkNode * current = mylist->head.pnext;
        for (i = 0; i < pos; i++)
        {
            current = current->pnext;
        }
        return current;
    }
    
    //删除线性链表指定位置的元素
    _declspec(dllexport)
    LinkNode* LinkList_Delete(LinkList* list, int pos){
        int ERRO_MSG = 0, i = 0;
        if (list == NULL)
        {
            ERRO_MSG = -1;
            printf("list==NULL 传入参数不可以为空! erro msg:%d
    ", ERRO_MSG);
            return NULL;
        }
        MyLinkList * mylist = (MyLinkList *)list;
        //判断获取元素的位置
        if (pos<0 || pos>mylist->length)
        {
            ERRO_MSG = -2;
            printf("该位置上没有元素! erro msg:%d
    ", ERRO_MSG);
            return NULL;
        }
        //这里跟获取元素位置离又不相同  这里current指向的是头结点
        LinkNode * current = &mylist->head;
        LinkNode * ret = NULL;
        for (i = 0; i < pos; i++)
        {
            current = current->pnext;
        }
        ret = current->pnext;
        current->pnext = ret->pnext;
        ret->pnext = NULL;
        //元素个数-1
        mylist->length--;
        return ret;
    }
    //线性链表测试代码
    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include"LinkList.h"
    
    typedef struct _Student{
        //必须加一个LinkNode节点
        LinkNode node;
        char name[30];
        int age;
    }Student;
    
    void Test(){
        Student s1, s2, s3, s4, s5;
        int numx = 0, i = 0, ret = 0;
        strcpy(s1.name, "小米");
        s1.age = 11;
        strcpy(s2.name, "小刚");
        s2.age = 12;
        strcpy(s3.name, "小红");
        s3.age = 10;
        strcpy(s4.name, "啸天");
        s4.age = 13;
        strcpy(s5.name, "莲华");
        s5.age = 12;
        //线性表指针
        LinkList *list = NULL;
        //创建线性链表
        list = LinkList_Create();
        //插入元素
        LinkList_Insert(list, (LinkNode *)&s1, 0);
        LinkList_Insert(list, (LinkNode *)&s2, 0);
        LinkList_Insert(list, (LinkNode *)&s3, 0);
        LinkList_Insert(list, (LinkNode *)&s4, 0);
        LinkList_Insert(list, (LinkNode *)&s5, 0);
        //获取元素个数
        numx = LinkList_Length(list);
        //打印所有元素
        for (i = 0; i < numx; i++)
        {
            Student *temp = (Student *)LinkList_Get(list, i);
            printf("我的名字是%s;我的年龄是%d
    ", temp->name, temp->age);
        }
        //删除线性表中的数据
        Student *delem = (Student *)LinkList_Delete(list, 2);
        printf("我被删除了,我的名字是%s;我的年龄是%d
    ", delem->name, delem->age);
        //销毁线性表
        ret = LinkList_Destroy(&list);
        if (ret == 0)printf("线性链表销毁成功!
    ");
    }
    
    void main(){
        Test();
        system("pause");
    }

     

  • 相关阅读:
    十天冲刺4
    单词统计
    十天冲刺3
    学习进度第十周
    十天冲刺2
    十天冲刺1
    梦断代码阅读笔记03
    学习进度第九周
    [强网杯 2019]Upload
    [2020 新春红包题]1
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5679714.html
Copyright © 2020-2023  润新知