数据结构,链表,单链表,双链表,循环链表,双向循环链表

链表是数据结构中的一个基本概念,它是线性表的一种实现。链表与顺序表(基于数组的线性表)不同,链表的元素不需要在内存中连续存储。链表的每个元素由一个节点来表示,每个节点都有一个数据部分和一个指针部分。

以下是链表的几种基本类型:

  1. 单链表:
  • 在单链表中,每个节点包含两部分:一个是数据部分,另一个是指向下一个节点的指针。

  • 最后一个节点的指针部分指向`NULL`,表示链表的结束。

以下是单链表节点的简单C语言表示:

cpp 复制代码
typedef struct Node {
    int data;           // 数据部分
    struct Node* next;  // 指向下一个节点的指针
} Node;

下面是单链表的基本操作,本次申请的单链表为有空头链表(头节点数据域为空,指针域指向下一个节点),也可以易申请无空头链表。

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
typedef int data_t;
 //构造链表节点类型
typedef struct node{
    data_t data;//保存数据的数据域
    struct node*next;//保存下一个节点的地址
} linklist ;

//创建链表的头节点
linklist* create_linklist();
//判空
int linklist_is_emtpy(linklist * head);
//求元素个数
int get_num_linklist(linklist* head);
//按位置插入
int insert_by_pos_linklist(linklist* head,int pos,data_t val);
//读数据
int printf_linklist(linklist*head);

int main()
{   
    linklist *head=create_linklist();
    for (int i = 0; i < 5; i++)
    {
        insert_by_pos_linklist(head,i,i+1);
    }
    printf_linklist(head);
    return 0;
}

//读数据
int printf_linklist(linklist*head)
{
    if(head==NULL) return -1;
    if(head->next->data==-1) return -1;
    while (NULL!=head->next)
    {
        printf("%d ",head->next->data);
        head=head->next;
    }
    printf("\n");
    return 0;
}

//创建链表的头节点
linklist* create_linklist()
{
    linklist*head=(linklist*)malloc(sizeof(linklist));
    if(NULL==head) return NULL;
    head->next=NULL;
    head->data=-1;
    return head;
}
//判空
int linklist_is_emtpy(linklist * head)
{
    if(NULL==head) return -1;
    return ((head->next==NULL)?1:0);
}
//求元素个数
int get_num_linklist(linklist* head)
{
    //判head
    if(NULL==head) return -1;
    linklist*p=head->next;//p=head
    int num=0;
    while (p!=NULL)//p->next!=NULL
    {
        num++;
        p=p->next;
    }
    return num;
}
//按位置插入
int insert_by_pos_linklist(linklist* head,int pos,data_t val)
{
    if (head==NULL) return -1;
    //判断位置合法性
    if(pos<0||pos>get_num_linklist(head)) return -1;
    //准备新节点
    linklist* new=(linklist*)malloc(sizeof(linklist));
    new->data=val;
    new->next=NULL;
    //先指向pos-1的位置
    linklist*p=head;
    while (pos--) p=p->next;
    //准备链接
    new->next=p->next;
    p->next=new;
    return 0;
}

2.双链表:

  • 双链表的每个节点有两个指针:一个指向下一个节点,另一个指向前一个节点。

  • 这使得从两个方向遍历链表都变得可能。

  1. 循环链表:
  • 循环链表与单链表相似,但其最后一个节点不是指向`NULL`,而是指回到第一个节点。

  • 这种结构形成了一个循环。

  1. 双向循环链表:
  • 这是双链表和循环链表的结合体。每个节点都有两个指针,一个指向前一个节点,另一个指向下一个节点。

  • 最后一个节点的下一个指针指向第一个节点,而第一个节点的前一个指针指向最后一个节点。

链表具有以下主要优点:

  • 动态大小:链表的大小可以在运行时动态更改,而无需预先分配或定义最大长度。

  • 插入和删除操作:与数组相比,链表中的元素可以更容易地插入或删除,不需要移动其他元素。

缺点:

  • 访问速度:链表不允许随机访问,要访问一个节点,可能需要从头节点开始遍历链表,直到找到所需的节点。

  • 更多的内存使用:由于每个节点都需要额外的指针来存储下一个节点的地址,因此链表使用的内存比数组更多。

  • 不利于缓存:链表的非连续内存存储可能不如数组那样利于CPU缓存。

在某些情况下,链表可能是最佳选择,当元素的插入和删除操作比元素的访问更为频繁时。

相关推荐
yuuki23323318 分钟前
【数据结构】用顺序表实现通讯录
c语言·数据结构·后端
还是码字踏实1 小时前
基础数据结构之数组的双指针技巧之对撞指针(两端向中间):三数之和(LeetCode 15 中等题)
数据结构·算法·leetcode·双指针·对撞指针
抠脚学代码5 小时前
Linux开发-->驱动开发-->字符设备驱动框架
linux·数据结构·驱动开发
星释8 小时前
Rust 练习册 8:链表实现与所有权管理
开发语言·链表·rust
熬了夜的程序员8 小时前
【LeetCode】101. 对称二叉树
算法·leetcode·链表·职场和发展·矩阵
橘颂TA9 小时前
【剑斩OFFER】算法的暴力美学——串联所有单词的字串
数据结构·算法·c/c++
葵续浅笑10 小时前
LeetCode - 杨辉三角 / 二叉树的最大深度
java·数据结构·算法·leetcode
Miraitowa_cheems10 小时前
LeetCode算法日记 - Day 94: 最长的斐波那契子序列的长度
java·数据结构·算法·leetcode·深度优先·动态规划
.ZGR.11 小时前
第十六届蓝桥杯省赛 C 组——Java题解1(链表知识点)
java·算法·链表·蓝桥杯
Paxon Zhang13 小时前
数据结构之**二叉树**超全秘籍宝典2
java·数据结构·算法