Toriyung

导航

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

链表

  本质上是一个结构体指向下一个结构体,第一个结构体为链头,重点是指向下一个(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 2022-10-28 22:15  Toriyung  阅读(24)  评论(0编辑  收藏  举报