C实现链表

简介

链表(Linked List)是一种常见的数据结构,用于存储一系列的元素。与数组不同,链表中的元素不必在内存中相邻地存储,而是通过指针来将它们连接起来。

链表由一系列 节点(Node) 组成,每个节点包含两部分:

  • 数据域:可以存储任意类型的数据;
  • 指针域:用于指向下一个节点或前一个节点。

链表的起始节点称为 头节点(Head) ,通常用一个指针指向它。链表的末尾节点通常指向一个 空值(NULL) ,表示链表的结束。

链表可以分为单向链表(单链表)和双向链表两种基本类型。

单向链表

单向链表(Single Linked List):每个节点只包含一个指针,指向下一个节点。单向链表只能从头节点开始沿着指针方向遍历链表,不能直接访问前一个节点。

双向链表

双向链表(Doubly Linked List):每个节点包含两个指针,一个指向前一个节点,一个指向后一个节点。双向链表可以从任意节点开始向前或向后遍历链表,可以直接访问前一个节点和后一个节点,因此在某些情况下操作更加灵活高效。

优点

  • 动态性:链表的长度可以动态调整,可以根据需要灵活地插入或删除节点。
  • 内存利用率:链表可以更好地利用内存,因为它不要求在内存中连续存储节点。
  • 插入和删除操作效率高:相比数组,链表在任意位置插入或删除节点的操作效率更高,时间复杂度为 O(1)。

缺点

  • 随机访问效率低:链表中的元素不是连续存储的,因此不能像数组那样通过下标随机访问元素,只能从头节点开始顺序访问。
  • 额外的空间开销:每个节点需要额外的指针来指向下一个节点或前一个节点,可能会占用一定的额外内存空间。
  • 不适合大量数据的操作:由于节点之间的指针关系,链表在处理大量数据时可能会产生额外的内存开销和时间开销。

尽管链表有一些缺点,但它仍然是一种常用的数据结构,特别适用于需要频繁插入和删除操作的场景,如实现栈、队列、哈希表等数据结构,以及某些算法问题的解决。

代码实现

单向链表

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

// 链表节点的结构定义
typedef struct Node {
    int val;
    struct Node* next;
} Node;

// 创建一个新节点
Node* createNode(int val) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    if (newNode == NULL) {
        printf("Memory allocation failed.\n");
        exit(1);
    }
    newNode->val = val;
    newNode->next = NULL;
    return newNode;
}

// 释放一个节点的内存
void freeNode(Node* node) {
    free(node);
}

int main() {
    // 创建节点
    Node* node1 = createNode(1);
    Node* node2 = createNode(2);
    Node* node3 = createNode(3);

    // 将节点连接起来形成链表
    node1->next = node2;
    node2->next = node3;

    // 遍历链表并打印节点的数据
    Node* cur = node1;
    while (cur != NULL) {
        printf("%d ", cur->val);
        cur = cur->next;
    }
    printf("\n");

    // 释放节点的内存
    Node* tmp;
    cur = node1;
    while(cur) {
        tmp = cur;
        cur = cur->next;
        freeNode(tmp);
    }

    return 0;
}

双向链表

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

typedef struct Node{
    int val;
    struct Node* prev;
    struct Node* next;
} Node;

Node* createNode(int val) {
    Node* node = (Node*)malloc(sizeof(Node));
    node->val = val;
    node->prev = NULL;
    node->next = NULL;
    return node;
}

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

int main() {
    Node* node1 = createNode(1);
    Node* node2 = createNode(2);
    Node* node3 = createNode(3);

    node1->next = node2;
    node2->prev = node1;
    node2->next = node3;
    node3->prev = node2;

    Node* cur = node1;
    while(cur) {
        printf("%d ", cur->val);
        cur = cur->next;
    }

    cur = node3;
    while(cur) {
        printf("%d ", cur->val);
        cur = cur->prev;
    }

    Node* tmp;
    cur = node1;
    while (cur) {
        tmp = cur;
        cur = cur->next;
        freeNode(tmp);
    }

    return 0;
}

posted @ 2024-05-07 11:14  岸南  阅读(21)  评论(0)    收藏  举报