2.5 线性表的链式表示和实现

2.5 线性表的链式表示和实现


  • 用一组物理位置任意的存储单元来存放线性表的数据元素
  • 这组存储单元既可以是连续的,也可以是不连续的,甚至是零散分布在内存中任意位置上
  • 链表中元素的逻辑次序和物理次序不一定相同。
  • 链式表相关术语
    1. 结点:数据元素的存储映像。由数据域和指针域两部分组成
    2. 链表:n个结点有指针链组成一个链表
      它是线性表的链式存储映像,称为线性表链式存储结构
  • 单链表、双链表、循环链表
    • 结点只有一个指针域的链表,称为单链表或线性链表
    • 结点有两个指针域的链表,称为双链表
    • 首尾相接的链表称为循环链表
  • 头指针、头结点和首元结点:
    • 头指针:是指向链表中第一个结点的指针
      !image

    • 首元结点:是指链表中存储第一个数据元素a1的结点

    • 头结点:是在链表的首元结点之前的附设的一个结点

  • 讨论1:如何表示空表
    无头结点时,头指针为空时表示空表
    有头结点时,当头结点的指针域为空时表示空表
  • 讨论2:在链表汇总设置头结点有什么好处?
    • 便于首元结点的处理
      首元结点的地址保存在头结点的指针域中,所以在链表的第一个位置上的操作和其他位置一致,无需进行特殊处理。
    • 便于空表和非空表的统一处理
      无论链表是否为空,头指针都是指向头结点的非空指针,因此空表和非空表的处理也就统一了。
  • 讨论3:头结点的数据域内装的是什么?
    头结点的数据域可以为空,也可存放线性表长度等附加信息,但此结点不能计入链表长度值。
  • 链表(链式存储结构)的特点
    • 结点在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理上不一定相邻
    • 访问时只能通过头指针进入链表,并通过每个结点的指针域依次向后顺序扫描其余结点,所以寻找第一个结点和最后一个结点所花费的时间不等

单链表的定义和表示


  • 单链表是由表头唯一确定,因此单链表可用头指针的名字来命名若头指针名是L,则把链表称为表L

  • 单链表的存储结构
    每一个结点包含两个部分:数据域和指针域

    typedef  struct Lnode{  // 声明结点类型和指向结点类型的指针类型
      ElemType data;			  // 结点的数据域
      struct Lnode  *next;   // 结点的指针域
    }Lnode,*LinkList;   		 // LinkList为指向结构体Lnode的指针类型
    

    ​ 定义链表L: LinkList L; 或者是Lnode *p;这两者是同样的意思。

单链表的基本操作和实现


  • 单链表的初始化(带头结点的单链表)

    • 构造一个空表

    • 【算法步骤】

      • 生成新结点作头结点,用头指针L指向头结点。
      • 将头结点的指针域置空。
    • 【算法描述】

      Status InitList(LinkList &L){
         L=new LNode;
        // 或 l =(LinkList)malloc(sizeof(LNode));
        L->next=NULL;   // 将生成头结点的指针域设置为空NULL
        return OK;
      }
      
  • 判断链表是否为空:

    • 链表中无元素,称为空链表(头指针和头结点仍然在)

    • 【算法思路】:判读头结点的指针域是否为空

    • 【算法描述】

      int  ListEmpty(LinkList L){
        if(L->next)
          return 0;
        else
          return 1;
      }
      
  • 单链表的销毁:链表销毁后不存在

    • 【算法思路】从头指针开始依次释放所有结点

    • 【算法描述】

      Status DestroyList(LinkList &L){
      		Lnode *p;
        	while(L){
            p=L;
            L=L->next;
            delete p;
          }
        	return OK;
      }
      
  • 单链表的清空:

    ​ 链表仍然存在,但链表中无元素,成为空链表(头指针和头结点仍然在)

    • 【算法思路】依次释放所有结点,并将头结点指针域设置为空

    • 【算法描述】

      Status ClearList(LinkList &L){
      		Lnode *p, *q;     // 定义两个指针变量
        	p=L->next;			  // p指针指向首元结点,同时p充当着指向当前结点的角色
        	while(p){				  // 利用p指针进行循环判定
            q=p->next;			 // 存储下一个结点的地址
            delete p;
            p=q;						// 移动当前指向指针
          }
        	L->next=NULL;			 // 将头结点的指针域设置为空。
        	return OK;
      }
      
  • 求单链表的表长:

    • 【算法思路】从首元结点开始,依次计数所有结点。

    • 【算法描述】

      int getLength(LinkList L){
        int length=0;
        LinkList p;
        p=L->next;
        while(p){
          length++;
          p=p->next;
        }
        return length;
      }
      
posted @   什么都会有的  阅读(47)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示