c语言数据结构 - 线性表的企业链式存储

概述

这个结构体 LinkNode ;
一个结构体占用的字节数是 4 个字节

code

#include "LinkList.h"


/**
 * 1. 首先定义数据类型,内部包含了 LinkNode 小挂钩(内部存放下一个节点地址) 和 数据域(内部存放name 和 age)
 * 定义其对象P1
 * 2. 使用一个LinkNode指针来指向 该对象 P1 地址且进行强制转换为 LinkNode 类型
 * (指针赋值相互操作的机制,因为是 指针类型是 LinkNode 类型, 而Person 第一个数据也是该类型
 * 所以使用该指针可以访问到第一快内存,若想访问到下面几个数据,需要手动计算需要跳过的字节数,获得其地址来进行访问)
 * 3. 插入的时候,只需要插入的 LinkNode 指针,也就是数据对象的地址就可以了
 * 相当于把地址串起来,使用的时候,获得该地址,再将其强转获得数据即可。
 */
typedef struct PERSON{
    LinkNode node; // 小挂钩 相等于一个next
    char name[64];
    int age;
}Person;

void test01();
void test02();
void test03();
void Myprint(LinkNode*);
int Mycompare(LinkNode*, LinkNode*);

int main(int argc, char**argv){

    test03();

    return 0;
}

void test01(){
    // 创建 一个链表
    LinkList* list = Init_LinkList();

    // 创建数据
    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;

    // 将节点插入到列表
    Insert_LinkList(list, 0, (LinkNode*)&P1);   // 这个data只能访问到 Person 中的 LinkNode 变量
    Insert_LinkList(list, 0, (LinkNode*)&P2); 
    Insert_LinkList(list, 0, (LinkNode*)&P3); 
    Insert_LinkList(list, 0, (LinkNode*)&P4); 
    Insert_LinkList(list, 0, (LinkNode*)&P5); 


    // 打印
    Print_LinkList(list, Myprint);


    // 释放内存
    FreeSpace_LinkList(list);
}

void test02(){
    // 创建 一个链表
    LinkList* list = Init_LinkList();

    // 创建数据
    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;

    // 将节点插入到列表
    Insert_LinkList(list, 0, (LinkNode*)&P1);   // 这个data只能访问到 Person 中的 LinkNode 变量
    Insert_LinkList(list, 0, (LinkNode*)&P2); 
    Insert_LinkList(list, 0, (LinkNode*)&P3); 
    Insert_LinkList(list, 0, (LinkNode*)&P4); 
    Insert_LinkList(list, 0, (LinkNode*)&P5); 


    // 打印
    Print_LinkList(list, Myprint);

    // 删除节点
    RemoveByPos_LinkList(list, 2);  

    // 打印
    Print_LinkList(list, Myprint);

    // 释放内存
    FreeSpace_LinkList(list);
}

void test03(){
    // 创建 一个链表
    LinkList* list = Init_LinkList();

    // 创建数据
    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;

    // 将节点插入到列表
    Insert_LinkList(list, 0, (LinkNode*)&P1);   // 这个data只能访问到 Person 中的 LinkNode 变量
    Insert_LinkList(list, 0, (LinkNode*)&P2); 
    Insert_LinkList(list, 0, (LinkNode*)&P3); 
    Insert_LinkList(list, 0, (LinkNode*)&P4); 
    Insert_LinkList(list, 0, (LinkNode*)&P5); 


    // 打印
    Print_LinkList(list, Myprint);


    // 查找
    Person findP;
    strcpy(findP.name, "ccc");
    findP.age = 30;
    printf("pos = %d\n", Find_LinkList(list, (LinkNode*)&findP, Mycompare));

    // 释放内存
    FreeSpace_LinkList(list);
}

void Myprint(LinkNode* data){
    // 1. 将数据类型再次转回来
    Person* p = (Person*)data;

    // 2. 打印数据
    printf("Name: %s\t Age: %d\n", p->name, p->age);
}

int Mycompare(LinkNode* node1, LinkNode* node2){

    // 1. 将数据类型再次转回来
    Person* p1 = (Person*)node1;
    Person* p2 = (Person*)node2;

    // 2. 判断
    if(strcmp(p1->name, p2->name) == 0 && p1->age == p2->age){
        return 0;
    }
    return -1;
}
#include "LinkList.h"

// 1. 初始化链表
LinkList* Init_LinkList(){
    // 这个时候头结点就不需要分配内存L
    LinkList* list = (LinkList*)malloc(sizeof(LinkList));

    list->head.next = NULL;
    list->size = 0;

    return list;
}  

// 2. 插入 需要注意,这里插入的是 LinkNode* 类型的数据
void Insert_LinkList(LinkList* list, int pos, LinkNode* data){

    // 2-1 判定参数的有效性
    if(list == NULL){
        return;
    }
    if(data == NULL){
        return;
    }

    // 插入末尾
    if(pos < 0 || pos > list->size){
        pos = list->size;
    }

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

    // 2-2-2 插入新节点 串接的是地址域
    data->next = pCurrent->next;
    pCurrent->next = data;

    list->size++;
}

// 3. 删除
void RemoveByPos_LinkList(LinkList* list, int pos){

    if(list == NULL){
        return;
    }

    if(pos < 0 || pos >= list->size){
        return;
    }

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

    // 删除内存:注意这里 插入的linkNode的时候并没有使用malloc来分配内存,所以释放内存的时候不需要使用free
    pCurrent->next = pCurrent->next->next;
    list->size--;
}

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

// 5. 打印
void Print_LinkList(LinkList* list, PRINTFNODE print){
    if(list == NULL){
        return;
    }

    LinkNode* pCurrent = list->head.next;   // 第一个有效值
    while(pCurrent != NULL){
        print(pCurrent);
        pCurrent = pCurrent->next;
    }

    printf("---------------------------------\n");

}

// 6. 释放内存空间
void FreeSpace_LinkList(LinkList* list){
    if(list == NULL){
        return;
    }

    free(list);
}

// 7. 查找
int Find_LinkList(LinkList* list, LinkNode* data, COMPARENODE compare){
    if(list == NULL){
        return -1;
    }
    if(data == NULL){
        return -1;
    }

    // 定义辅助变量,因为是需要查找,所以辅助变量初始化为头结点的next位置
    LinkNode* pCurrent = list->head.next;
    int index = 0;   
    int flag = -1;
    while (pCurrent != NULL)
    {
        // 找到逻辑的判断
        // 需要一个比较的函数指针和遍历的函数指针
        if(compare(pCurrent, data) == 0) // 相等返回0
        {
            flag = index;
            break;
        }
        // 遍历下一个
        pCurrent = pCurrent->next;
        index++;    // 遍历是从第0开始
    }
    
    return flag;
}

#ifndef LINK_LIST_H
#define LINK_LIST_H

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


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

// 链表节点
typedef struct LINKLIST
{
    LinkNode head;
    int size;
}LinkList;


// 定义一个函数指针
typedef void(*PRINTFNODE)(LinkNode*);

// 定义一个比较的函数类型
typedef int(*COMPARENODE)(LinkNode*, LinkNode*);

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

// 2. 插入 需要注意,这里插入的是 LinkNode* 类型的数据
void Insert_LinkList(LinkList* list, int pos, LinkNode* data);

// 3. 删除
void RemoveByPos_LinkList(LinkList* list, int pos);

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

// 5. 打印
void Print_LinkList(LinkList* list, PRINTFNODE print);

// 6. 释放内存空间
void FreeSpace_LinkList(LinkList* list);

// 7. 查找
int Find_LinkList(LinkList* list, LinkNode* data, COMPARENODE compare);

#endif


# commands
gcc -fPIC -shared LinkList.c -o liblinkList1.so
gcc main.c -o main -L ./ -llinkList1 -Wl,-rpath ./
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值