千家信息网

c#中单链表有什么用

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要介绍了c#中单链表有什么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。不带头节点链表单向链表是链表的一种。单向链表由一系
千家信息网最后更新 2026年11月02日c#中单链表有什么用

这篇文章主要介绍了c#中单链表有什么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

不带头节点链表

单向链表是链表的一种。单向链表由一系列内存不连续的节点组成,每个节点都包含指向值的域和指向下个节点的next指针。最后一个节点的next域为NULL值,代表链表结束。

链表示意图如下:

一,结构体

1,结构体定义:

struct LinkNode{    void *x;     struct LinkNode *next;};

2,结构体大小:

1)取结构体大小方法:sizeof(struct LinkNode);在64位系统取出结构体大小为:sizeof(struct LinkNode) = 16;

2)为什么是16字节:因为本结构体包含的两个指针成员x和next。指针是存放地址的,故在同一系统平台下,指针变量取的sizeof大小都是一致。即对于指针变量的大小并不取决于指针类型,而取决于系统平台。32位=4字节,64位=8字节。故有在64位系统中sizeof(void *) == sizeof(struct LinkNode *) == 8。在32位系统中,sizeof(void *) == sizeof(struct LinkNode *) == 4。

3)若假设节点ABCD是内存连续的且A作为内存其起始点,即A的地址为0x00,那么此时B,C,D的地址就依次为:0x10,0x20,0x30。且A的next指针指向的是节点B(A->next = &B),依次类推,直到节点D的next存的是结束符NULL。

二,链表创建

1,链表创建一(使用一级指针)

程序说明:

1)程序调用方式szyu_link_create1("AA", "BB", NULL),NULL用于正确终止for循环。

2)创建新增节点node。

3)如果链表为空,则先把新增节点(node)赋值给head,并让last指向最新的head;如果链表不为空,则把尾节点的next指向最新节点,并重新赋值尾节点即可。

struct LinkNode*szyu_link_create1(void *x, ...){    struct LinkNode *head = NULL;    struct LinkNode *last = head;    va_list args;    va_start(args, x);    for ( ; x ; x = va_arg(args, void *) )    {        struct LinkNode *node = NULL;        node = (struct LinkNode *)malloc(sizeof(struct LinkNode));        if ( node == NULL )        {            return head;        }        node->x = x;        node->next = NULL;        if ( head == NULL )        {            head = node;            last = head;        }        else         {            last->next = node;            last = node;        }    }    va_end(args);    return head;}

2,链表创建二(使用二级指针)

程序说明:

1)二级指针node存在如下成立等式:*node == head,**node = *head;

2)for刚开始为*node(*node = head)创建空间,既创建头节点。

3)为(*node)节点的x赋值,并让指针node指向新节点的next,即赋值后*node即为前node的next域值。

4)第二次for开始,为*node赋值就是给(*node)->next赋值。

5)重复步骤3,4直到NULL传入为止。

6)最后一个节点把node指向next后并未对其进行赋NULL值处理。故在for循环结束要为*node赋值NULL。代表链表结束。

struct LinkNode*szyu_link_create2(void *x, ...){    struct LinkNode *head  = NULL;    struct LinkNode **node = &head;    va_list args;    va_start(args, x);     for ( ; x; x = va_arg(args, void *) )    {           (*node) = (struct LinkNode *)malloc(sizeof(struct LinkNode));        if ( (*node) == NULL )        {               return head;        }           (*node)->x = x;        node = &(*node)->next;    }       *node = NULL;    va_end(args);    return head;}

3,一级指针和二级指针对比

一级指针

1)优点:程序通俗易懂。

2)缺点:插入头节点和插入其他位置方式不同,代码风格不统一。

二级指针

1)优点:无论插入什么位置,代码风格高度统一。代码精简。

2)缺点:技巧性较高。

4,设计思路

二级指针的使用场景就是"间接改变一级指针所指向的内存地址"。而改变的一级指针指向的即为next指针。除头节点外的所有节点新增地址都存在上一节点的next中,固有设计node指向next,为*node赋值时即为next赋值。

三,链表插入

1,链表插入一(使用一级指针)

程序说明:

1)key的判断保证输入位置不能小于1,并可以在链表最后面插入新节点。

2)初始化新增节点。

3)int cnt = 2;在key = 1时,是要重新插入第一个节点;key = 2 时插入的前一个节点即为第一节点。所以在key <= 2时是不需要进行链表移动,故cnt = 2开始执行。

4)由于不带头节点,故在插入时,插入在头节点位置和后面位置需要区分考虑。

struct LinkNode*szyu_link_insert1(struct LinkNode *head, void *x, int key){    if ( head == NULL )    {        return head;    }    int len = szyu_link_length2(head);    if ( key < 1 || key - 1 > len )    {        return head;    }    struct LinkNode *node = NULL;    node = (struct LinkNode *)malloc(sizeof(struct LinkNode));    if ( node == NULL )    {        return head;    }    node->x = x;    node->next = NULL;    struct LinkNode *list = head;        int cnt = 2;    for ( ; cnt < key; cnt++ )    {        list = list->next;    }    if ( key == 1 )    {        node->next = head;        head = node;    }    else    {        node->next = list->next;        list->next = node;    }    return head;}

2,链表插入二(使用二级指针)

程序说明:

1)key - 1是保证在链表后面插入节点正常。

2)由于使用二级指针故cnt初始化为1即可,无须单独考虑插入头节点情况。

struct LinkNode                                                                           *szyu_link_insert2(struct LinkNode *head, void *x, int key){    if ( head == NULL )    {        return head;    }    int len = szyu_link_length2(head);    if ( key < 1 || key - 1 > len )    {        return head;    }    struct LinkNode **list = &head;    int cnt = 1;    while ( cnt < key )    {        list = &(*list)->next;        cnt += 1;    }    struct LinkNode *remain = *list;    *list = (struct LinkNode *)malloc(sizeof(struct LinkNode));    if ( (*list) == NULL )    {        return head;    }    (*list)->x = x;    (*list)->next = remain;    return head;}

3,使用一级指针和二级指针优缺点同链表创建

4,使用二级指针设计思路

1)首先使二级指针list指向一级指针head。

2)循环使用链表停留在插入位置的前一节点上。此时若不是头节点位置,list指向的是插入位置前一节点的next,插入时,只需为*list赋值新节点地址即可。若是头节点,则*list指向头节点。

3)无论是否为头节点,把剩下链表赋值给remain(若插入为头节点,此时remain保留的事整个链表;若插入在最后,则remain为NULL)。

4)为*list赋值新节点地址。并把remain追加到*list节点后面即可。

四,链表节点删除

1,链表节点删除(一级指针)

程序说明:

1)如果头节点为要删除节点,只需要把head指向head->next即可。

2)由于delete停留在要删除节点的前一节点,故只需要把delete->next赋值给remain,在free即可。

struct LinkNode*szyu_link_delete1(struct LinkNode *head, void *x){    if ( head == NULL )    {        return NULL;    }    struct LinkNode *delete = head;    struct LinkNode *remain = NULL;    if ( strcmp((char *)delete->x, (char *)x) == 0 )    {        remain = delete;        head = delete->next;    }    else    {        while ( delete->next != NULL && strcmp((char *)delete->next->x, (char *)x) != 0)        {            delete = delete->next;                                                          }        remain = delete->next;        delete->next = delete->next->next;    }    free(remain);    return head;}

2,链表节点删除(二级指针)

程序说明

1)若为头节点时,*list = head,head = head->next即可,即为*list = (*list)->next。

2)若不为头节点,list是指向next的指针,此时*list即为下个节点,若要删除下个节点,为*list重新赋值即可改变下个节点指向。

struct LinkNode*szyu_link_delete2(struct LinkNode *head, void *x) {    if ( head == NULL )    {           return head;    }       struct LinkNode **list = &head;    while ( (*list) != NULL && strcmp((char *)(*list)->x, (char *)x) != 0 )     {           list = &(*list)->next;    }       struct LinkNode *remain = *list;    (*list) = (*list)->next;    free(remain);    return head;}

五,链表释放

程序说明:

1)使用二级指针后的*head即为删除节点。

voidszyu_link_free2(struct LinkNode **head){    if ( *head == NULL || head == NULL )    {        return;    }    struct LinkNode *next = NULL;    for ( ; *head; *head = next )    {        next = (*head)->next;        free(*head);                                                                    }}

六,链表长度获取

程序说明:

1)由于链表不带头节点,故直接赋值head链表。

intszyu_link_length2(struct LinkNode *head){    if ( head == NULL )    {        return 0;    }    struct LinkNode *pLen = head;    int len = 0;    for ( ; pLen != NULL; pLen = pLen->next )    {        len += 1;    }    return len;}

七,链表打印

voidszyu_link_print1(struct LinkNode *head){    if ( head == NULL )    {        return;    }    struct LinkNode *print = head;    for ( ; print != NULL; print = print->next )    {        printf("%s ", (char *)print->x);    }    printf("\n");}

感谢你能够认真阅读完这篇文章,希望小编分享的"c#中单链表有什么用"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

节点 指针 指向 程序 位置 地址 结构 大小 系统 内存 篇文章 代码 字节 循环 设计 c# 代表 优点 取决于 变量 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 手磨咖啡 百单网互联网科技有限公司怎么样 互联网是不是新科技 互联网最新的科技有限公司 网络科技有限互联网 互联网科技金融公司 济南和联互联网科技有限公司 安控科技rtu产品工业互联网 移动互联网科技股 宜昌元轩互联网科技有限公司 互联网科技扶贫时间 互联网在线教育科技创业 互联网科技公司营业执照怎么办理 互联网第三次科技革命特征 九思连强互联网电子科技有限公司 广州梦谷互联网科技有限公司领导 安徽零酒互联网科技有限公司 深圳互联网科技园地址 保山浩联互联网科技有限公司 互联网企业和网络科技有限公司 互联网和科技创新 唐信互联网科技 大连 兼蜜互联网科技 荆州市昕露互联网络科技有限公司 呼和浩特新华互联网科技学院 开一家科技互联网公司需要多少钱 华夏恒生科技与互联网科技 广州千川互联网科技有限公司 西安左小互联网科技有限公司 安徽零酒互联网科技有限公司
0