数据结构 线性链表

//线性链表头文件
#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");
}

 

原文地址:https://www.cnblogs.com/zhanggaofeng/p/5679714.html