单链表的一些概念


链表是一种物理存储单元上非连续、非顺序的存储结构,由一系列结点组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

一、链表概念

单链表是一种常见的线性数据结构,它由一系列节点组成,每个节点包含两部分:数据域和指针域。数据域用于存储数据,指针域则指向下一个节点。单链表的特点是节点在内存中是分散存储的,通过指针将它们连接起来,形成一个线性序列。

以下是单链表的一些关键特性和操作:

单链表的特点

  1. 动态存储:单链表的节点可以根据需要动态分配和释放,不需要预先分配固定大小的存储空间。

  2. 插入和删除操作高效:在单链表中插入或删除节点时,只需要修改相邻节点的指针,而不需要移动其他节点,时间复杂度为O(1)。

  3. 随机访问效率低:单链表不支持随机访问,访问某个节点需要从头节点开始逐个遍历,时间复杂度为O(n)。

  4. 占用额外空间:每个节点需要额外存储一个指针,因此会占用比数组更多的内存空间。

单链表的基本操作

  1. 创建单链表

    • 可以通过头插法或尾插法创建单链表。

    • 头插法:每次新节点插入到头节点之后,时间复杂度为O(1)。

    • 尾插法:每次新节点插入到链表的尾部,需要维护一个尾指针,时间复杂度为O(1)。

  2. 插入节点

    • 在指定位置插入节点,需要找到插入位置的前驱节点,然后修改指针。

  3. 删除节点

    • 删除指定位置的节点,需要找到该节点的前驱节点,然后修改指针。

  4. 查找节点

    • 从头节点开始逐个遍历,直到找到目标节点或到达链表末尾。

  5. 遍历链表

    • 从头节点开始,依次访问每个节点,直到到达链表末尾。

  6. 反转链表

    • 通过修改节点的指针方向,将链表的顺序反转。

  7. 合并链表

    • 将两个有序链表合并为一个有序链表。

单链表的实现(C语言示例)

以下是单链表的基本实现代码:

#include 
#include 

// 定义节点结构
typedef struct Node {
    int data; // 数据域
    struct Node* next; // 指针域,指向下一个节点
} Node;

// 创建新节点
Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

// 插入节点(尾插法)
void insertNode(Node** head, int data) {
    Node* newNode = createNode(data);
    if (*head == NULL) {
        *head = newNode; // 如果链表为空,直接将新节点作为头节点
    } else {
        Node* temp = *head;
        while (temp->next != NULL) {
            temp = temp->next; // 找到尾节点
        }
        temp->next = newNode; // 将新节点插入到尾部
    }
}

// 打印链表
void printList(Node* head) {
    Node* temp = head;
    while (temp != NULL) {
        printf("%d -> ", temp->data);
        temp = temp->next;
    }
    printf("NULL\n");
}

// 主函数
int main() {
    Node* head = NULL; // 初始化空链表
    insertNode(&head, 10);
    insertNode(&head, 20);
    insertNode(&head, 30);
    printList(head); // 输出:10 -> 20 -> 30 -> NULL
    return 0;
}

单链表的应用场景

  1. 动态数据集合:当数据大小不确定时,单链表可以动态扩展。

  2. 内存管理:用于管理内存碎片,如操作系统中的空闲内存块管理。

  3. 队列和栈的实现:通过单链表可以实现队列和栈的基本操作。

如果你有更具体的问题,比如单链表的某种操作或者实现细节,可以告诉我,我会进一步为你解答!

三、总结
常考的知识点:链表的插入,删除的关键语句、在头部插入,中间插入,尾部插入的时间复杂度,以及单链表和顺序表的区别

在链表尾部添加(addLast())需要从头遍历,时间复杂度为O(n)
在链表头部添加(addFirst()),时间复杂度为O(1)
在链表任意位置添加(add(int index,E e)),平均情况下为O(n/2)=O(n)

单链表和顺序表的区别:

顺序表的优点:

元素可以随机存储
节省存储空间
元素位置可用一个简单、直观的公式表示并在常量时间内访问
顺序表的缺点:

在作插入或删除操作时,需要移动大量元素
单链表的优点:

链表是线性表的链式存储表示
链表中逻辑关系相邻的元素不一定在存储位置上相连,用一个链(指针)表示元素之间的邻接关系即:链表中结点的逻辑顺序和物理顺序不一定相同
在插入和删除时,不需要大量移动数据元素,只需找到结点,对该结点做删除和插入的工作即可
单链表的缺点:

在访问第i个位置的元素时,需遍历链表,不能想顺序表一样直接找到第i个位置

你可能感兴趣的:(c语言,算法)