链表 删除时 辅助指针指不到,要删除元素内 维护 的指针 。 pCurrent->next = pCurrent->next->next;

img

img

LinkList.h

#pragma once


#ifndef __COMPANY_LINKLIST_H
#define __COMPANY_LINKLIST_H

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

//链表小节点
typedef struct LINKNODE
{
    struct LinkNode* next;
}LinkNode;

//链表节点
typedef struct LINKList
{
    //实例化一个节点 将其设为头部 且他的nex永远指向 链表的第一个元素
    LinkNode head;
    int size;

}LinkList;

//声明一个遍历 函数指针
typedef void(*PRINTNODE)(LinkNode*);

//比较函数指针
typedef int(*COMPARENODE)(LinkNode*, LinkNode*);

//初始化链表
LinkList* Init_LinkList();

//根据下标 插入          参1链表   参2下标  参3小节点  
void Insert_LinkList(LinkList* list, int pos, LinkNode* data);

//删除  
void Remove_LinkList(LinkList* list, int pos);

//查找 根据值返回下标
int Find_LinkList(LinkList* list, LinkNode* data, COMPARENODE compare);

//返回链表 大小 
int Size_LinkList(LinkList* list);

//打印  
void Print_LinkList(LinkList* list, PRINTNODE print);

//释放链表内存  
void FreeSpace_LinkList(LinkList* list);

#endif // !LINKLIST_H

03 企业链表.c

#include"LinkList.h"

//自定义数据类型
typedef struct PERSON
{
    LinkNode node;
    char name[64];//64个字节
    int age;//姓名
    
}Person;


//打印函数  //因为函数名是内存首地址  所以传递的 print=MyPrint
void MyPrint(LinkNode* data)
{
    //构造一个类型的 指针指向真实内存,上传的数据地址,框小了,转成大框
    //LinkNode*转成Person* 此时框柱了完整数据的 内存
    Person* p = (Person*)data;
    //格式说明由“%”和格式字符组成,如%d%f等。它的作用是将输出的数据转换为指定的格式输出。格式说明总是由“%”字符开始的。不同类型的数据用不同的格式字符。
    printf("Name:%s Age:%d\n", p->name, p->age);
}

int MyCompare(LinkNode*nodel1, LinkNode* nodel2)
{
    Person* p1 = (Person*)nodel1;
    Person* p2 = (Person*)nodel2;
    if (strcmp(p1->name, p2->name) == 0 && p1->age == p2->age)
    {
        return 0;
    }
    return -1;
}


int main() {

    //创建链表  Init_LinkList() 此函数才是开辟内存,并且将内存用指针返回
    LinkList* lisit = Init_LinkList();
    printf("size:%d\n",sizeof(lisit));

    //创建数据类型
    Person p1, p2, p3, p4, p5;
    strcpy(p1.name, "aaa");
    strcpy(p2.name, "bbb");
    strcpy(p3.name, "ccc");
    strcpy(p4.name, "ddd");
    strcpy(p5.name, "eee");

    p1.age = 10;
    p2.age = 20;
    p3.age = 30;
    p4.age = 40;
    p5.age = 50;

    //数据入链表
    //位置选0类似头插,全插在脑袋上
    //先传入p1类型的指针,但是p1指针指向的内存大了,转成LinkNode*的指针,将框变小,
    //类似p1里有节点钩子(LinkNode node;)这个p1的钩子会钩住p2的钩子
    Insert_LinkList(lisit, 0, (LinkNode*)&p1);
    Insert_LinkList(lisit, 0, (LinkNode*)&p2);
    Insert_LinkList(lisit, 0, (LinkNode*)&p3);
    Insert_LinkList(lisit, 0, (LinkNode*)&p4);
    Insert_LinkList(lisit, 0, (LinkNode*)&p5);
    
    //打印  //因为函数名是内存首地址  所以传递的 print=MyPrint 
    //甚至此时用 引用的方式也可以传值 下面用指针可以,
    // 因为本质上就是传递  函数的首地址

    Print_LinkList(lisit, MyPrint);
    printf("--------------------------------------\n");


    //删除  根据下标删除
    Remove_LinkList(lisit, 0);
    Print_LinkList(lisit, MyPrint);
    printf("--------------------------------------\n");

    //查找
    Person findP;
    strcpy(findP.name, "ccc");
    findP.age = 30;
    int pos=Find_LinkList(lisit, (LinkNode*)&findP, MyCompare);
    printf("位置:%d\n", pos);


    ////返回第一个节点  如果是是空链表 这里很危险 目前我还不知道怎么解决
    //Person* ret = (Person*)Front_LinkList(lisit);

    //printf("retName:%s retAge:%d retScore:%d\n", ret->name, ret->age);
    //printf("--------------------------------------\n");

    //销毁链表
    FreeSpace_LinkList(lisit);




    printf("\n");
    system("pause");
    return 0;

}

LinkList.c

#include"LinkList.h"



//初始化链表
LinkList* Init_LinkList()
{
    LinkList* list = (LinkList*)malloc(sizeof(LinkList));
    list->head.next = NULL;
    list->size = 0;

    return list;
}

//根据下标 插入          参1链表   参2下标  参3小节点  
void Insert_LinkList(LinkList* list, int pos, LinkNode* data)
{
    if (list == NULL)
    {
        return-1;
    }
    if (data == NULL)
    {
        return-1;
    }
    if (pos<0 || pos>list->size)
    {
        pos = list->size;
    }


    //查找插入位置
    LinkNode* pCurrent = &(list->head);
    for (int i = 0; i < pos; i++)
    {
        pCurrent = pCurrent->next;

    }

    //插入新节点
    data->next = pCurrent->next;
    pCurrent->next = data;

    list->size++;
}

//删除  
void Remove_LinkList(LinkList* list, int pos)
{
    if (list == NULL)
    {
        return-1;
    }
    if (pos<0 || pos>=list->size)
    {
        return-1;
    }

    LinkNode* pCurrent = &list->head;
    
    for (int i = 0; i < pos; i++)
    {
        pCurrent = pCurrent->next;
    
    }
    pCurrent->next = pCurrent->next->next;
    list->size--;
}

//查找
int Find_LinkList(LinkList* list, LinkNode* data, COMPARENODE compare)
{

    if (list == NULL)
    {
        return -1;
    }
    if (data == NULL)
    {
        return-1;
    }
    
    LinkNode* pCurrent = list->head.next;

    int index = 0;
    int flag = -1;
    while (pCurrent!=NULL)
    {
        if (compare(pCurrent, data) == 0)
        {
            flag = index;
            break;
        }
        pCurrent = pCurrent->next;
        index++;
    }


    return flag;


}

//返回链表 大小 
int Size_LinkList(LinkList* list)
{
    return 0;


}

//打印  
void Print_LinkList(LinkList* list, PRINTNODE print)
{
    if (list == NULL)
    {
        return-1;
    }
    //辅助指针
    LinkNode* pCurnent = list->head.next;

    while (pCurnent!=NULL)
    {
        print(pCurnent);

        pCurnent = pCurnent->next;
    }
    

}

//释放链表内存  
void FreeSpace_LinkList(LinkList* list)
{
    if (list == NULL)
    {
        return-1;
    }
    free(list);

}