数据结构学习(day01)

1.数据结构基本概念

数据结构是相互之间存在一种或多种特定关系的数据元素的集合。它是计算机存储、组织数据的方式,直接影响程序的效率和性能。

2.数据结构分类

1.逻辑结构

集合结构:所有数据都在一个集合中,元素间关系平等。

线性结构:数据之间是一对一的关系,如数组、链表。

树状结构:数据之间是一对多的关系,如二叉树、B树。

2.物理结构(存储结构)

顺序存储:数据存储在连续的存储单元中,如数组。

链式存储:数据存储单元可以是任意的,通过指针连接,如链表。

链式存储概述

线性表的链式存储(单向链表)解决了顺序存储的以下问题:

  • 插入和删除效率低(顺序表需要移动大量元素)
  • 动态存储问题(顺序表需要预先分配固定空间)

特点:

存储单元可以是连续的,也可以是不连续的。

每个节点(Node)包含:

数据域:存储数据元素

指针域:存储下一个节点的地址通过指针链接各个节点,形成链式结构。

单向链表的基本操作(C语言实现)

头文件定义
c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int DATATYPE;  // 数据类型可自定义

typedef struct LinkNode {
    DATATYPE data;          // 数据域
    struct LinkNode *next;  // 指针域
} LinkNode;

typedef struct LinkList {
    LinkNode *head;  // 头指针
    int clen;        // 当前链表长度
} LinkList;
创建链表
c 复制代码
LinkList *CreateLinkList() {
    LinkList *ll = (LinkList *)malloc(sizeof(LinkList));
    if (ll == NULL) {
        fprintf(stderr, "CreateLinkList malloc failed\n");
        return NULL;
    }
    ll->head = NULL;
    ll->clen = 0;
    return ll;
}
头插法
c 复制代码
int InsertLinkList(LinkList *ll, DATATYPE *data) {
    if (ll == NULL || data == NULL) {
        fprintf(stderr, "Invalid arguments\n");
        return 1;
    }
    LinkNode *newnode = (LinkNode *)malloc(sizeof(LinkNode));
    if (newnode == NULL) {
        fprintf(stderr, "InsertLinkList malloc failed\n");
        return 1;
    }
    memcpy(&newnode->data, data, sizeof(DATATYPE));
    newnode->next = ll->head;  // 新节点指向原头节点
    ll->head = newnode;        // 更新头指针
    ll->clen++;
    return 0;
}
判断链表是否为空
c 复制代码
int IsEmptyLinkList(LinkList *ll) {
    if (ll == NULL) {
        fprintf(stderr, "Invalid argument\n");
        return -1;
    }
    return (ll->head == NULL) ? 1 : 0;
}
显示链表
c 复制代码
void ShowLinkList(LinkList *ll) {
    if (ll == NULL || ll->head == NULL) {
        printf("LinkList is empty\n");
        return;
    }
    LinkNode *temp = ll->head;
    while (temp != NULL) {
        printf("%d -> ", temp->data);
        temp = temp->next;
    }
    printf("NULL\n");
}
查找节点
c 复制代码
LinkNode *SearchLinkList(LinkList *ll, DATATYPE key) {
    if (ll == NULL || ll->head == NULL) {
        return NULL;
    }
    LinkNode *temp = ll->head;
    while (temp != NULL) {
        if (temp->data == key) {
            return temp;
        }
        temp = temp->next;
    }
    return NULL;
}
删除节点
c 复制代码
int DeleteLinkList(LinkList *ll, DATATYPE key) {
    if (ll == NULL || ll->head == NULL) {
        fprintf(stderr, "LinkList is empty\n");
        return 1;
    }
    LinkNode *prev = NULL;
    LinkNode *curr = ll->head;
    while (curr != NULL) {
        if (curr->data == key) {
            if (prev == NULL) {  // 删除头节点
                ll->head = curr->next;
            } else {             // 删除中间或尾节点
                prev->next = curr->next;
            }
            free(curr);
            ll->clen--;
            return 0;
        }
        prev = curr;
        curr = curr->next;
    }
    fprintf(stderr, "Key not found\n");
    return 1;
}

总结

操作 时间复杂度 说明
头插法 O(1) 直接在头部插入
尾插法 O(n) 需要遍历到链表末尾
查找 O(n) 最坏情况遍历整个链表
删除 O(n) 需要找到目标节点

优点:

动态分配内存,无需预先指定大小

插入和删除高效(O(1) 头插,O(n) 随机位置)

缺点:

访问元素需要遍历(O(n))

额外存储指针,占用更多内存

相关推荐
晴天的雨.9922 小时前
【C++算法】和为s的两个数
开发语言·数据结构·c++·算法
M78佐菲7 小时前
ARM学习笔记(1)
linux·arm开发·笔记·嵌入式硬件·学习
嵌入式阿蔡8 小时前
嵌入式虚拟化2026:Hypervisor从数据中心走进MCU
嵌入式
无敌贵点大王9 小时前
RTThread学习记录11——RT-Thread 设备模型吃透:UART/ADC/PWM/PIN 到底有什么区别?
c语言·stm32·学习·链表
淡海水10 小时前
13-04-面试-源码级深度追问链
数据结构·unity·面试·c#·游戏引擎·源码·il2cpp
Logic10110 小时前
C语言/数据结构位运算题解:异或XOR找出时尚聚会中的“独特颜色“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
是翎11 小时前
深度长文|2026产品经理AI实践手册
人工智能·深度学习·学习·自然语言处理·数据挖掘
Linux-lucky11 小时前
32-38-Linux学习之旅之MySQL综合
linux·运维·学习·mysql·ubuntu
知识分享小能手12 小时前
C++ 学习教程,从入门到精通,C++ 入门知识 — 完整知识点(1)
开发语言·c++·学习
2401_8390805413 小时前
C++常见八股
数据结构·c++·算法