C语言实现通用数据结构之通用链表

C语言是一门广泛应用于低级别系统编程的语言,也是数据结构和算法学习的重要工具之一,而在C语言中实现通用数据结构的方法之一就是通用链表。

通用链表是一种使用节点来组织数据的通用数据结构,每个节点包含一定量的数据以及指向链表中下一个节点的指针,因此,它可以用来实现许多不同的数据结构,例如栈、队列、树、图、哈希表等等。

具体实现通用链表的方法如下:

步骤一:定义节点结构体

首先,我们需要定义节点(Node)结构体,它包含两个变量,data表示存储的数据,next表示指向下一个节点的指针。

typedef struct Node {
    void *data;
    struct Node *next;
} Node;

步骤二:定义链表结构体

其次,我们需要定义链表(List)结构体,它包含一个头节点(head)以及链表中节点的个数(size)。

typedef struct List {
    Node *head;
    int size;
} List;

步骤三:实现节点的创建和释放函数

接下来,我们需要实现节点的创建和释放函数。create_node()函数用来创建新节点,它需要输入一个void类型的数据,返回一个新的Node类型的节点。free_node()函数用来释放一个节点的内存,它需要输入一个Node指针。

Node *create_node(void *data) {
    Node *node = (Node*) malloc(sizeof(Node));
    node->data = data;
    node->next = NULL;
    return node;
}

void free_node(Node *node) {
    free(node);
}

步骤四:实现链表的创建和销毁函数

然后,我们需要实现链表的创建和销毁函数。create_list()函数用来创建新链表,它返回一个新的List类型的链表。free_list()函数用来销毁一个链表及其所有节点的内存,它需要输入一个List指针。

List *create_list() {
    List *list = (List*) malloc(sizeof(List));
    list->head = NULL;
    list->size = 0;
    return list;
}

void free_list(List *list) {
    Node *node = list->head;
    while (node != NULL) {
        Node *tmp = node;
        node = node->next;
        free_node(tmp);
    }
    free(list);
}

步骤五:实现链表的增加、删除和查找函数

接下来,我们需要实现链表的增加、删除和查找函数。add_node()函数用来在链表尾部添加一个新节点,它需要输入一个List指针以及一个void类型的数据。remove_node()函数用来从链表中删除一个节点,它需要输入一个List指针以及一个Node指针。find_node()函数用来查找链表中是否存在一个包含特定数据的节点,它需要输入一个List指针以及一个比较函数指针。

void add_node(List *list, void *data) {
    Node *node = create_node(data);
    if (list->head == NULL) {
        list->head = node;
    } else {
        Node *tmp = list->head;
        while (tmp->next != NULL) {
            tmp = tmp->next;
        }
        tmp->next = node;
    }
    list->size++;
}

void remove_node(List *list, Node *node) {
    if (list->head == node) {
        list->head = node->next;
    } else {
        Node *tmp = list->head;
        while (tmp != NULL && tmp->next != node) {
            tmp = tmp->next;
        }
        if (tmp != NULL) {
            tmp->next = node->next;
        }
    }
    free_node(node);
    list->size--;
}

Node *find_node(List *list, void *data, int (*cmp)(void*, void*)) {
    Node *node = list->head;
    while (node != NULL) {
        if ((*cmp)(node->data, data) == 0) {
            return node;
        } else {
            node = node->next;
        }
    }
    return NULL;
}

步骤六:使用示例

下面,我们通过两个使用示例来说明通用链表的用法。

在第一个示例中,我们将使用通用链表来实现栈(堆栈)数据结构。首先,我们需要定义一个简单的数据结构,包含一个整型变量num。然后,我们使用通用链表来实现栈,push()函数用来将数据压入栈中,pop()函数用来从栈中弹出数据,空栈时返回NULL。

typedef struct Item {
    int num;
} Item;

void push(List *list, int num) {
    Item *item = (Item*) malloc(sizeof(Item));
    item->num = num;
    add_node(list, item);
}

Item *pop(List *list) {
    if (list->size == 0) {
        return NULL;
    } else {
        Node *node = list->head;
        while (node->next != NULL) {
            node = node->next;
        }
        Item *item = (Item*) node->data;
        remove_node(list, node);
        return item;
    }
}

在第二个示例中,我们将使用通用链表来实现哈希表(散列表)数据结构。首先,我们需要定义一个简单的数据结构,包含一个字符串变量key和一个整型变量value。然后,我们使用通用链表来实现哈希表,insert()函数用来插入一对键值对,search()函数用来查找特定键对应的值。

typedef struct KeyValue {
    char *key;
    int value;
} KeyValue;

unsigned int hash(char *key) {
    unsigned int hash = 0;
    while (*key != '\0') {
        hash = *key + (hash << 6) + (hash << 16) - hash;
        key++;
    }
    return hash;
}

void insert(List **table, char *key, int value) {
    unsigned int index = hash(key) % MAX_TABLE_SIZE;
    KeyValue *kv = (KeyValue*) malloc(sizeof(KeyValue));
    kv->key = key;
    kv->value = value;
    if (table[index] == NULL) {
        table[index] = create_list();
    }
    add_node(table[index], kv);
}

int *search(List **table, char *key) {
    unsigned int index = hash(key) % MAX_TABLE_SIZE;
    Node *node = table[index]->head;
    while (node != NULL) {
        KeyValue *kv = (KeyValue*) node->data;
        if (strcmp(kv->key, key) == 0) {
            return &(kv->value);
        } else {
            node = node->next;
        }
    }
    return NULL;
}

以上就是完整的C语言实现通用数据结构之通用链表的攻略过程,以及两个示例的说明。当然,这只是一个简单的实现,还可以不断优化和完善,例如加入迭代器、排序、合并等操作。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言实现通用数据结构之通用链表 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • C++高级数据结构之线段树

    C++高级数据结构之线段树攻略 什么是线段树 线段树是一种数据结构,它可以支持区间查询和单点修改,是处理静态区间问题的常用手段。它利用了 二分思想,将区间离散化成一些个体,然后考虑对个体进行处理,再结合区间合并的特性,更新区间信息。线段树主要由四个操作构成:建树、单点修改、区间查询和区间修改。 线段树的数据表示 在实现线段树时,我们需要考虑数据结构的几个要素…

    数据结构 2023年5月17日
    00
  • Codeforces Round 868 Div 2

    A. A-characteristic (CF 1823 A) 题目大意 要求构造一个仅包含\(1\)和 \(-1\)的长度为 \(n\)的数组 \(a\),使得存在 \(k\)个下标对 \((i, j), i < j\)满足 \(a_i \times a_j = 1\)。 解题思路 当有\(x\)个 \(1\), \(y\)个 \(-1\)时,其满足…

    算法与数据结构 2023年4月30日
    00
  • 【ACM博弈论】SG函数入门(1):从巴什博奕到尼姆游戏

    在我小时候以前做题的时候,遇到博弈题往往都是漫无目的地打表找规律,或者找一些特殊情况但是没有很好的分析方法。 其实博弈题是有比较套路的解题方法的,那就是利用SG函数,第一节不会讲到SG函数的具体用法,我们先来博弈入个门,学习一下最基本的博弈类型:Nim游戏。 ? 作者:Eriktse? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式…

    算法与数据结构 2023年4月17日
    00
  • Golang Mutex互斥锁源码分析

    Golang Mutex互斥锁源码分析 介绍 Golang的Mutex互斥锁机制是一种非常重要的并发控制方式,它可以保证在同一时刻,同一共享资源只能被一个goroutine访问,其他的goroutine必须等待当前访问者释放锁之后才能访问该共享资源。 在使用Mutex机制时,需要进行锁定、解锁等操作,而这一过程是由Mutex的底层实现——sync包来完成的。…

    数据结构 2023年5月17日
    00
  • 数据结构C语言链表的实现介绍

    数据结构C语言链表的实现介绍 1. 什么是链表? 链表是一种常见的数据结构,它由一系列的节点(Node)通过链接(Link)组成,每个节点包含两个部分:数据域(Data)和指针(Pointer),数据域用来存储数据,指针用来链接下一个节点。链表最重要的优点就是支持动态扩展,占用内存比较灵活,相比于数组,链表在增加和删除元素时更加高效。 2. 链表的实现 链表…

    数据结构 2023年5月17日
    00
  • Python数据结构之顺序表的实现代码示例

    针对“Python数据结构之顺序表的实现代码示例”,我可以给出以下完整攻略: 什么是顺序表 顺序表是一种线性结构,是用一维数组来存储数据元素的有序集合。它支持随机访问,可以对任意位置的元素进行查找、插入、删除等操作。 顺序表的实现代码示例 以下是Python中实现顺序表的示例代码,以及相关的操作函数,包括创建空表、获取表长度、查找元素、插入元素、删除元素等。…

    数据结构 2023年5月17日
    00
  • Go 数据结构之堆排序示例详解

    Go 数据结构之堆排序示例详解 什么是堆? 堆(Heap)是一种特殊的树形数据结构,它满足下列性质: 堆中每个节点的关键字都不大于(或不小于)其子节点的关键字。 堆中,根节点(顶端)是最小或最大元素。 堆实际上是一个完全二叉树,因此可以用数组实现。对于下标为i的节点,其左子节点为2i,右子节点为2i+1,父节点为i/2。 堆分为最大堆和最小堆。在最大堆中,父…

    数据结构 2023年5月17日
    00
  • 1811 E Living Sequence 两种解法

    思维 进制转换 数位DP 无前导0 T3Problem – 1811E – Codeforces 题目大意 从一个不含有数字4的递增序列中找第k个数并输出。如 \(1,2,3,5,6,7,8,9,10,11,12\), \(k = 4\) 时输出 \(5\)。 思路1 有一个巧妙的解法:考虑这个问题, 从一个没有限制的从1开始的递增序列找出第k个数, 显然就…

    算法与数据结构 2023年4月17日
    00
合作推广
合作推广
分享本页
返回顶部