zoukankan      html  css  js  c++  java
  • 数据结构 传统链表实现与Linux内核链表

    头文件:

    #pragma once
    
    #include<stdlib.h>
    
    
    //链表结点
    struct LinkNode{
        void *data;
        struct LinkNode *next;
    };
    
    //链表
    struct _Linklist{
        struct LinkNode header;
        int size; //链表结点的数目
    };
    
    typedef void *LinkList;
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
        //初始化链表
        LinkList Init_LinkList();
        //指定位置插入
        int InsertByPos_LinkList(LinkList list, int pos, void *data);
        //头插
        int PushFront_LinkList(LinkList list, void *data);
        //尾插
        int PushBack_LinkList(LinkList list, void *data);
        //在指定值的前面插入
        int InsertByVal_LinkList(LinkList list, void *oldval, void *newval, int(*isequal)(void*,void*));
        //指定位置删除
        int RemoveByPos_LinkList(LinkList list, int pos);
        //根据值删除
        int RemoveByVal_LinkList(LinkList list, void *data, int(*compare)(void *, void *));
        //头删
        void PopFront_LinkList(LinkList list);
        //尾删
        void PopBack_LinkList(LinkList list);
        //遍历
        void Foreach_LinkList(LinkList list, void(*foreach)(void *));
        //销毁
        void Destroy_LinkList(LinkList list);
    
    #ifdef __cplusplus
    }
    #endif

    头文件实现:

    #include"LinkList.h"
    
    
    //初始化链表
    LinkList Init_LinkList(){
    
        struct _Linklist *list = malloc(sizeof(struct _Linklist));
        if (NULL == list){
            return NULL;
        }
    
        list->header.data = NULL;
        list->header.next = NULL;
        list->size = 0;
    
        return list;
    }
    //指定位置插入 0代表插入到第一个位置
    int InsertByPos_LinkList(LinkList list, int pos, void *data){
    
        if (NULL == list){
            return -1;
        }
    
        if (NULL == data){
            return -2;
        }
    
        struct _Linklist *llist = (struct _Linklist *)list;
    
        if (pos < 0 || pos > llist->size){
            pos = llist->size;
        }
    
        //辅助指针变量
        struct LinkNode *pCurrent = &(llist->header);
        for (int i = 0; i < pos;i ++){
            pCurrent = pCurrent->next;
        }
    
        //创建新结点
        struct LinkNode *newnode = malloc(sizeof(struct LinkNode));
        newnode->data = data;
        newnode->next = NULL;
    
        //新结点入链表
        newnode->next = pCurrent->next;
        pCurrent->next = newnode;
    
        //size
        llist->size++;
    
        return 0;
    }
    //头插
    int PushFront_LinkList(LinkList list, void *data){
        return InsertByPos_LinkList(list, 0, data);
    }
    //尾插
    int PushBack_LinkList(LinkList list, void *data){
        if (NULL == list){
            return -1;
        }
        struct _Linklist *llist = (struct _Linklist *)list;
        return InsertByPos_LinkList(list,llist->size - 1,data);
    }
    //在指定值的前面插入
    int InsertByVal_LinkList(LinkList list, void *oldval, void *newval, int(*isequal)(void*, void*)){
        if(NULL ==list){
            return -1;
        }
    
        if (NULL == oldval){
            return -2;
        }
    
        if (NULL == newval){
            return -3;
        }
    
        if (NULL == isequal){
            return -4;
        }
    
        struct _Linklist *llist = (struct _Linklist *)list;
    
        //辅助指针变量
        struct LinkNode *pPrev = &(llist->header);
        struct LinkNode *pCurrent = pPrev->next;
        while (pCurrent != NULL){
            
            if (isequal(pCurrent->data, oldval)){
                
                //创建新结点
                struct LinkNode *newnode = malloc(sizeof(struct LinkNode));
                newnode->data = newval;
                newnode->next = NULL;
    
                //新结点入链表
                pPrev->next = newnode;
                newnode->next = pCurrent;
    
                llist->size++;
    
                break;
            }
    
            pPrev = pCurrent;
            pCurrent = pCurrent->next;
        }
        
        return 0;
    }
    //指定位置删除
    int RemoveByPos_LinkList(LinkList list, int pos){
    
        if (NULL == list){
            return -1;
        }
    
        struct _Linklist *llist = (struct _Linklist *)list;
    
        if (llist->size == 0){
            return 0;
        }
    
        if (pos < 0 || pos > llist->size - 1){
            return 0;
        }
    
        //辅助指针变量
        //找到待删除结点的前一个结点
        struct LinkNode *pCurrent = &(llist->header);
        for (int i = 0; i < pos;i ++){
            pCurrent = pCurrent->next;
        }
    
        //缓存下待删除结点
        struct LinkNode *pDel = pCurrent->next;
        //重新建立待删除结点的前驱后继结点关系
        pCurrent->next = pDel->next;
        //删除结点内存
        free(pDel);
        pDel = NULL;
    
        llist->size--;
    
        return 0;
    }
    //根据值删除
    int RemoveByVal_LinkList(LinkList list, void *data, int(*compare)(void *, void *)){
    
        if (NULL == list){
            return -1;
        }
    
        if (NULL == data){
            return -2;
        }
    
        if (NULL == compare){
            return -3;
        }
    
        struct _Linklist *llist = (struct _Linklist *)list;
        //辅助指针变量
        struct LinkNode *pPrev = &(llist->header);
        struct LinkNode *pCurrent = pPrev->next;
    
        while (pCurrent != NULL){
            
            if (compare(pCurrent->data, data)){
                
                pPrev->next = pCurrent->next;
                free(pCurrent);
                llist->size--;
                break;
            }
    
            pPrev = pCurrent;
            pCurrent = pPrev->next;
        
        }
    
        return 0;
    }
    //头删
    void PopFront_LinkList(LinkList list){
        RemoveByPos_LinkList(list, 0);
    }
    //尾删
    void PopBack_LinkList(LinkList list){
        if (NULL == list){
            return;
        }
        struct _Linklist *llist = (struct _Linklist *)list;
        RemoveByPos_LinkList(list, llist->size - 1);
    }
    //遍历
    void Foreach_LinkList(LinkList list, void(*foreach)(void *)){
    
        if (NULL == list){
            return;
        }
    
        if (NULL ==    foreach){
            return;
        }
    
        struct _Linklist *llist = (struct _Linklist *)list;
    
        //辅助指针变量
        struct LinkNode *pCurrent = llist->header.next;
        while (pCurrent != NULL){
            foreach(pCurrent->data);
            pCurrent = pCurrent->next;
        }
    
    }
    //销毁
    void Destroy_LinkList(LinkList list){
    
        if (NULL == list){
            return;
        }
    
        struct _Linklist *llist = (struct _Linklist *)list;
    
        //辅助指针变量
        struct LinkNode *pCurrent = llist->header.next;
        while (pCurrent != NULL){
            
            //缓存下一个结点
            struct LinkNode *pNext = pCurrent->next;
            //释放当前结点内存
            free(pCurrent);
            //指针移动到下一个结点的位置
            pCurrent = pNext;
    
        }
    
        free(llist);
        llist = NULL;
    }

    测试代码:

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include"LinkList.h"
    
    struct Person{
        char name[64];
        int age;
    };
    
    
    void MyPrint(void *data){
        struct Person *person = (struct Person *)data;
        printf("Name:%s Age:%d
    ", person->name,person->age);
    }
    
    int MyCompare(void *d1,void *d2){
        struct Person *p1 = (struct Person *)d1;
        struct Person *p2 = (struct Person *)d2;
        return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
    }
    
    void test(){
    
        //创建测试数据
        struct Person p1 = { "aaa", 10 };
        struct Person p2 = { "bbb", 20 };
        struct Person p3 = { "ccc", 30 };
        struct Person p4 = { "ddd", 40 };
        struct Person p5 = { "eee", 50 };
        struct Person p6 = { "fff", 60 };
        struct Person p7 = { "ggg", 70 };
        
        //初始化链表
        LinkList list = Init_LinkList();
        //将数据插入链表
        InsertByPos_LinkList(list, 0, &p1);
        InsertByPos_LinkList(list, 0, &p2);
        InsertByPos_LinkList(list, 0, &p3); 
        InsertByPos_LinkList(list, 1, &p4);
        InsertByPos_LinkList(list, 0, &p5);
        InsertByPos_LinkList(list, 0, &p6);
        //遍历 6 5 3 4 2 1
        Foreach_LinkList(list, MyPrint);
        printf("-------------------
    ");
        printf("在name为ccc,age为30的数据前面插入:
    ");
        InsertByVal_LinkList(list, &p3, &p7, MyCompare);
        Foreach_LinkList(list, MyPrint);
        printf("删除位置4的数据:
    ");
        RemoveByPos_LinkList(list,4);
        Foreach_LinkList(list, MyPrint);
        printf("删除name为ggg age为70的数据:
    ");
        RemoveByVal_LinkList(list, &p7, MyCompare);
        Foreach_LinkList(list, MyPrint);
    
        //销毁链表
        Destroy_LinkList(list);
    }
    
    int main(){
    
        test();
    
        system("pause");
        return EXIT_SUCCESS;
    }

    链表版本二:通过修改指针的指向的区域的大小,实现数据链接,给用户使用

    头文件:

    #pragma once
    
    #include<stdlib.h>
    
    //链表小节点
    
    //目的 : 第一,让用户数据包含 第二,我需要把用户指针类型转换成struct LinkNode*类型
    struct LinkNode{
        struct LinkNode *next;
    };
    
    //链表结构体
    struct LList{
        struct LinkNode header;
        int size;
    };
    
    typedef void *LinkList;
    
    //初始化
    LinkList Init_LinkList();
    
    //指定位置插入
    void Insert_LinkList(LinkList list, int pos, struct LinkNode *data);
    //位置删除
    void RemoveByPos_LinkList(LinkList list, int pos);
    //遍历
    void Foreach_LinkList(LinkList list, void(*foreach)(void *));
    
    //销毁
    void Destroy_LinkList(LinkList list);

    头文件实现:

    #include"LinkList.h"
    
    
    //初始化
    LinkList Init_LinkList(){
    
        struct LList *list = malloc(sizeof(struct LList));
        if (NULL == list){
            return NULL;
        }
        list->header.next = NULL;
        list->size = 0;
    
        return list;
    }
    //指定位置插入
    void Insert_LinkList(LinkList list, int pos, struct LinkNode *data){
        
        if (NULL == list){
            return;
        }
    
        if (NULL == data){
            return;
        }
        
        struct LList *llist = (struct LList *)list;
    
        if (pos < 0 || pos >llist->size){
            pos = llist->size;
        }
    
        //查找pos位置前一个位置的节点
        struct LinkNode *pCurrent = &(llist->header);
        for (int i = 0; i < pos;i ++){
            pCurrent = pCurrent->next;
        }
    
        //将新节点插入到链表
        data->next = pCurrent->next;
        pCurrent->next = data;
    
        llist->size++;
    }
    
    //位置删除
    void RemoveByPos_LinkList(LinkList list, int pos){
    
        if (NULL ==list){
            return;
        }
    
        struct LList *llist = (struct LList *)list;
    
    
        if (llist->size == 0){
            return;
        }
    
        if (pos < 0 || pos > llist->size - 1){
            return;
        }
    
    
        //找到pos位置的前一个节点
        struct LinkNode *pCurrent = &(llist->header);
        for (int i = 0; i < pos; i ++){
            pCurrent = pCurrent->next;
        }
    
        //缓存下待删除节点
        struct LinkNode *pDel = pCurrent->next;
        //重新建立待删除的节点前驱后继节点关系
        pCurrent->next = pDel->next;
    
        llist->size--;
    }
    
    //遍历
    void Foreach_LinkList(LinkList list, void(*foreach)(void *)){
        if (NULL == list){
            return;
        }
    
        struct LList *llist = (struct LList *)list;
        //辅助指针变量
        struct LinkNode *pCurrent = llist->header.next;
        while (pCurrent != NULL){
            foreach(pCurrent);
            pCurrent = pCurrent->next;
        }
    }

    测试函数:

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include"LinkList.h"
    
    struct Person{
        struct LinkNode node;
        char name[64];
        int age;
    };
    
    void MyPrint(void *data){
        struct Person *person = (struct Person *)data;
        printf("Name:%s Age:%d
    ",person->name,person->age);
    }
    
    void ChanageValue(void *data){
        struct Person *person = (struct Person *)data;
        person->age += 100;
    }
    
    //#define ISSTACK
    
    void test(){
    
        //创建测试数据
    #ifdef ISSTACK
        struct Person p1 = { NULL , "aaa", 10 };
        struct Person p2 = { NULL , "bbb", 20 };
        struct Person p3 = { NULL , "ccc", 30 };
        struct Person p4 = { NULL , "ddd", 40 };
        struct Person p5 = { NULL , "eee", 50 };
    #else
        struct Person *p1 = malloc(sizeof(struct Person));
        struct Person *p2 = malloc(sizeof(struct Person));
        struct Person *p3 = malloc(sizeof(struct Person));
        struct Person *p4 = malloc(sizeof(struct Person));
        struct Person *p5 = malloc(sizeof(struct Person));
    
    
        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;
    
    #endif
    
        //初始化链表
        LinkList list = Init_LinkList();
    #ifdef ISSTACK
        //数据插入到链表
        Insert_LinkList(list, 0, (struct LinkNode *)&p1);
        Insert_LinkList(list, 0, (struct LinkNode *)&p2);
        Insert_LinkList(list, 0, (struct LinkNode *)&p3);
        Insert_LinkList(list, 0, (struct LinkNode *)&p4);
        Insert_LinkList(list, 0, (struct LinkNode *)&p5);
    #else
        Insert_LinkList(list, 0, (struct LinkNode *)p1);
        Insert_LinkList(list, 0, (struct LinkNode *)p2);
        Insert_LinkList(list, 0, (struct LinkNode *)p3);
        Insert_LinkList(list, 0, (struct LinkNode *)p4);
        Insert_LinkList(list, 0, (struct LinkNode *)p5);
    #endif
        //遍历
        Foreach_LinkList(list, MyPrint);
    
        //删除2号位置
        printf("------------------
    ");
        RemoveByPos_LinkList(list, 3);
        Foreach_LinkList(list, MyPrint);
    
        //遍历修改数据
        printf("---------------------
    ");
        //Foreach_LinkList(list, ChanageValue);
        //Foreach_LinkList(list, MyPrint);
    
        //销毁链表
        Destroy_LinkList(list);
    
        free(p1);
        free(p2);
        free(p3);
        free(p4);
        free(p5);
    
    }
    
    int main(){
    
        test();
    
        system("pause");
        return EXIT_SUCCESS;
    }

    以链表为底层容器实现栈

    头文件:

    容器头文件:

    #pragma once

    #include<stdlib.h>

    //链表小节点

    //目的 : 第一,让用户数据包含 第二,我需要把用户指针类型转换成struct LinkNode*类型
    struct LinkNode{
    struct LinkNode *next;
    };

    //链表结构体
    struct LList{
    struct LinkNode header;
    int size;
    };

    typedef void *LinkList;

    //初始化
    LinkList Init_LinkList();

    //指定位置插入
    void Insert_LinkList(LinkList list, int pos, struct LinkNode *data);
    //位置删除
    void RemoveByPos_LinkList(LinkList list, int pos);
    //遍历
    void Foreach_LinkList(LinkList list, void(*foreach)(void *));
    //根据位置获得值
    void *Get_LinkList(LinkList list,int pos);
    int Size_LinkList(LinkList list);


    //销毁
    void Destroy_LinkList(LinkList list);

    栈头文件:

    #pragma once
    
    #include"LinkList.h"
    
    struct StackNode{
        struct LinkNode node;
    };
    
    typedef void *LinkStack;
    
    //初始化
    LinkStack Init_LinkStack();
    //入栈
    void Push_LinkStack(LinkStack stack, void *data);
    //出栈
    void Pop_LinkStack(LinkStack stack);
    //获得栈顶元素
    void *Top_LinkStack(LinkStack stack);
    //大小
    int Size_LinkStack(LinkStack stack);
    //销毁栈
    void Destroy_LinkStack(LinkStack stack);

    头文件实现:

    容器头文件实现:

    #include"LinkList.h"
    
    
    //初始化
    LinkList Init_LinkList(){
    
        struct LList *list = malloc(sizeof(struct LList));
        if (NULL == list){
            return NULL;
        }
        list->header.next = NULL;
        list->size = 0;
    
        return list;
    }
    //指定位置插入
    void Insert_LinkList(LinkList list, int pos, struct LinkNode *data){
        
        if (NULL == list){
            return;
        }
    
        if (NULL == data){
            return;
        }
        
        struct LList *llist = (struct LList *)list;
    
        if (pos < 0 || pos >llist->size){
            pos = llist->size;
        }
    
        //查找pos位置前一个位置的节点
        struct LinkNode *pCurrent = &(llist->header);
        for (int i = 0; i < pos;i ++){
            pCurrent = pCurrent->next;
        }
    
        //将新节点插入到链表
        data->next = pCurrent->next;
        pCurrent->next = data;
    
        llist->size++;
    }
    
    //位置删除
    void RemoveByPos_LinkList(LinkList list, int pos){
    
        if (NULL ==list){
            return;
        }
    
        struct LList *llist = (struct LList *)list;
    
    
        if (llist->size == 0){
            return;
        }
    
        if (pos < 0 || pos > llist->size - 1){
            return;
        }
    
    
        //找到pos位置的前一个节点
        struct LinkNode *pCurrent = &(llist->header);
        for (int i = 0; i < pos; i ++){
            pCurrent = pCurrent->next;
        }
    
        //缓存下待删除节点
        struct LinkNode *pDel = pCurrent->next;
        //重新建立待删除的节点前驱后继节点关系
        pCurrent->next = pDel->next;
    
        llist->size--;
    }
    
    
    //根据位置获得值
    void *Get_LinkList(LinkList list, int pos){
        if (NULL == list){
            return NULL;
        }
    
        struct LList *llist = (struct LList *)list;
        if (pos < 0 || pos > llist->size - 1){
            return NULL;
        }
    
        //辅助指针变量
        struct LinkNode *pCurrent = &(llist->header);
        for (int i = 0; i < pos; i++){
            pCurrent = pCurrent->next;
        }
    
    
        return pCurrent->next;
    }
    
    int Size_LinkList(LinkList list){
        if (NULL == list){
            return -1;
        }
    
        struct LList *llist = (struct LList *)list;
        return llist->size;
    }
    
    
    //遍历
    void Foreach_LinkList(LinkList list, void(*foreach)(void *)){
        if (NULL == list){
            return;
        }
    
        struct LList *llist = (struct LList *)list;
        //辅助指针变量
        struct LinkNode *pCurrent = llist->header.next;
        while (pCurrent != NULL){
            foreach(pCurrent);
            pCurrent = pCurrent->next;
        }
    }
    
    //销毁
    void Destroy_LinkList(LinkList list){
        if (NULL == list){
            return;
        }
    
        free(list);
        list = NULL;
    }

    栈头文件实现:

    #include"LinkStack.h"
    
    //初始化
    LinkStack Init_LinkStack(){
        return Init_LinkList();
    }
    //入栈
    void Push_LinkStack(LinkStack stack, void *data){
        Insert_LinkList(stack, 0, data);
    }
    //出栈
    void Pop_LinkStack(LinkStack stack){
        RemoveByPos_LinkList(stack, 0);
    }
    //获得栈顶元素
    void *Top_LinkStack(LinkStack stack){
        return Get_LinkList(stack, 0);
    }
    //大小
    int Size_LinkStack(LinkStack stack){
        return Size_LinkList(stack);
    }
    //销毁栈
    void Destroy_LinkStack(LinkStack stack){
        Destroy_LinkList(stack);
    }

    测试文件

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include"LinkStack.h"
    
    struct Person{
        struct StackNode node;
        char name[64];
        int age;
    };
    
    void test(){
    
        //创建测试数据
        struct Person p1 = { NULL, "aaa", 10 };
        struct Person p2 = { NULL, "bbb", 20 };
        struct Person p3 = { NULL, "ccc", 30 };
        struct Person p4 = { NULL, "ddd", 40 };
        struct Person p5 = { NULL, "eee", 50 };
        //初始化栈
        LinkStack stack = Init_LinkStack();
        //数据入栈
        Push_LinkStack(stack , &p1);
        Push_LinkStack(stack, &p2);
        Push_LinkStack(stack, &p3);
        Push_LinkStack(stack, &p4);
        Push_LinkStack(stack, &p5);
        //输出栈中元素
        while (Size_LinkStack(stack) > 0){
        
            //获得栈顶元素
            struct Person *person = (struct Person*)Top_LinkStack(stack);
            //输出元素
            printf("Name:%s Age:%d
    ",person->name,person->age);
            //弹出栈顶元素
            Pop_LinkStack(stack);
    
        }
    
        printf("Size%d
    ",Size_LinkStack(stack));
    
        //销毁栈
        Destroy_LinkStack(stack);
    }
    
    int main(){
    
        test();
    
        system("pause");
        return EXIT_SUCCESS;
    }
  • 相关阅读:
    windows server 2008 r2 切换windows 7主题方法
    JAVA环境安装
    Oracle 11gR2 安装教学
    webmin-1.810 安装
    Windows Squid 安装配置
    Zyxel Switch-How to block a fake DHCP server without enabling DHCP snooping?
    Java介绍
    cookies和session区别
    牛刀小试之Django二
    小试牛刀之Django
  • 原文地址:https://www.cnblogs.com/w-x-me/p/6780998.html
Copyright © 2011-2022 走看看