Toriyung

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

数据结构整理笔记(未完)

链表

  本质上是一个结构体指向下一个结构体,第一个结构体为链头,重点是指向下一个(next)结构体

  代码实现

  创建链表

复制代码
struct Element   //链表元素
{
   char *name;    
   struct Element *next;      //名为next的结构体的指针
};    


struct List    //链头
{ 
   char *name;
   struct Element *next;      //名为next的结构体的指针        
};

//分别创建结构体对象L1,A1
struct List L1;
struct Element A1;

L1.name = "L1";
L1.next = NULL;    //此时没有链表元素,链头下一个结构体对象不存在

A1.name = "A1";
A1.next = NULL;    //A1的下一个结构体对象不存在

L1.next = &A1;    //链头的下一个结构体对象为A1
复制代码

  删除链表

    当需要在List中删除A项,执行以下判断

    先令指针pre = NULL,p = A。进行循环判断。当p不为NULL和不为A时,pre=p,p=p->next,进下一次循环。当p为NULL时直接返回,表示List没有A项;当p为A时即找到需要删除的元素,则pre从指向p改成指向NULL,表示pre已是队尾,p踢出链表;当循环结束pre仍为NULL时表示A是链表第一个元素,则pre指向A后面的元素,即pre = p->next。

 

通用链表

  很容易看出来,当结构体不同时,链表操作函数需要跟着多一套出来。所以需要一个通用链表

  原理:

    之前的普通链表使用的是对应结构体的下一个结构体的指针next,next指向结构体的头部,于是next指针本身具有针对性(针对特定个结构体),如下图

  

 

 

  而通用链表,是先定义一个节点结构体node,嵌入每个结构体owner,类似于结构体身上带着一块牌子,通过节点结构体之间的联系找到对应的结构体,node结构体内部只有一个元素,就是下一个node的指针next。如此一来链表也一样使用node节点,无视结构体差异如下图

  

 

  那么,如何由node找出其owner?有以下三种方式

    1. node节点放在owner结构体的第一位,则node节点地址本身等于owner地址

    2. node节点放在owner结构体的固定偏移位,通过计算推断

    3. node节点内部设置一个指针,指向owner结构体,所以在初始化node节点时也需要一并传入owner地址

  而node所在的链表称之为其container

 

 

    

posted on   Toriyung  阅读(29)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示