数据结构——线性表

本文详细介绍了线性表的概念,包括其定义、逻辑特性以及两种主要的存储结构:顺序存储和链式存储。顺序存储具有随机访问的优势,但插入和删除效率较低;链式存储则允许动态分配内存,但不支持随机访问。文章还探讨了不同类型的链表(单链表、双链表、循环链表等)及其优缺点,并给出了相关代码示例。
摘要由CSDN通过智能技术生成

一、线性表

这篇总结的主要是线性表的知识点,可以收藏下来,哪些地方概念不是特别清楚的时候翻出来看看。如果想看本章涉及到的代码部分,见文章下方超链接。

另外有些地方序号可能排版比较乱,之前在Typora上写的,导入过来之后貌似排序受到了影响,希望不影响阅读。

(一)线性表的下定义和基本操作
  1. 定义:

    • 线性表是具有相同特性数据元素的一个有限序列。该序列中所含元素的个数叫做线性表的长度,用n(n>=0)表示,n=0表示线性表是一个空表。
    • 另外一个数据元素也可以由若干个数据项组成,在这种情况下,常把数据元素称为记录。例如:表格中的一行的数据项:姓名,性别,电话等,含有大量记录的线性表称为文件。
  2. 逻辑特性:

    • 只有一个表头元素,只有一个表尾元素,表头元素没有前驱,表尾元素没有后继,除了表头,表尾外,其他元素只有一个直接前驱和一个直接后继。
  3. 存储结构:

    • 顺序存储结构----顺序表
    • 链式存储结构----链表
  4. 基本操作:

    /******************************部分代码实现如上方超链接*********************************/
    - Initlist(&L)					        	//构造一个空的线性表L
    - DestoryList(&L)                       	//销毁线性表L
    - ClearList(&L)                            	//将线性表L重置为0
    - ListEmpty(L)                             	//判断线性表是否为空 
    - ListLength(L)                            	//返回线性表L的数据元素个数
    - GetElem(L,i,&e)                          	//用e来返回线性表L中第i个数据元素
    - LocateElem(L,e,compare())    				//返回L中与e满足关系的数据元素的位序
    - PriorElem(L,cur_e,&pre_e)     			//用pre_e返回cur_e的前驱
    - NextElem(L,cur_e,&next_e)    				//用next_e返回cur_e的后继
    - ListInsert(&L,i,e)                       	//在L中的第i个位置插入新的数据元素e
    - ListDelete(&L,i,&e)                   	//删除L中的第i个元素,用e返回其值
    - ListTraverse(L,visit())                	//对L中的每个元素调用函数visit()             
    
(二)线性表的实现
  1. 顺序存储

    • 顺序存储就是把线性表中的所有元素按照其逻辑顺序依次存储到指定的存储位置开始的一块连续的存储空间中。

    • 优点:

      • 可以随机访问数组中的元素——随机访问特性
      • 逻辑相邻,物理相邻——占有连续的存储空间
      • 存储空间使用紧凑——存储空间利用率高
    • 缺点:

      • 插入,删除需要移动大量元素
      • 预先分配空间需要按照最大使用空间分配,利用不充分
      • 表容量难以扩充
    • 核心代码

      #define MAX_SIZE 30				//设置顺序表最大容量
      typedef struct
      {
      	int data[MAX_SIZE];			//设置数据最大长度
      	int length;					//设置数据当前长度
      
      }Sqlist;
      
  2. 链式存储

    • 链式存储中,每个结点不仅包含所存元素的信息,还包含元素之间逻辑关系的信息

    • 优点:

      • 动态分配内存空间
      • 插入,删除无需移动元素
      • 由于内存是随机分配的,使得数据删除后覆盖率低,恢复可能提高
    • 缺点:

      • 不支持随机访问,
      • 查找节点时,链式存储比顺序存储慢
      • 比顺序存储结构的存储密度稍小——存储空间利用率比较低
    • 链表的5种表现形式

      • 单链表

        • 每个结点种不仅除了包含数据域外,还包含一个指针域,用以指向其后继结点。

        • 核心代码

          typedef struct LNODE
          {
          	int data;						//数据域
          	struct LNODE* next;				//指针域
          }LNODE;
          
        • 图形所示,便于理解

        [外链图(img-WAKEpbEF1564582507551)(C:\Users\DONG\AppData\RoDTaming\eypora\typora-usimages\r56458484127120C.png:\Users\DONG\AppData\Roaming\Typora\typora-user-images\1564581248420.png)(C:\Users\DONG\AppData\Roaming\Typora\typora-user-images\1564581248420.png)]

        • 这里顺便说一下头结点,也就是上图看到的Head指针的这个结点。
          • 带头结点的单链表中,头指针Head指向头结点,头结点数据域不包含任何信息,从头结点的后继结点开始存放数据信息。头指针Head始终不等于NULL,head->next 等于NULL说明链表为空
          • 不带头结点的单链表中,头指针Head指向开始结点,当head等于NULL的时候,链表为空。
      • 双链表

        • 由于单链表只能从开始结点走到终端结点,不能返回。因此双链表就是为了解决这种问题的。双链表在单链表的基础上增添了一个指针域,指向当前结点的前驱。

        • 核心代码

          typedef struct DLNODE
          {
          	int data;							//存放结点中的数据
          	struct DLNODE *prior;				//指向前驱结点的指针
          	struct DLNODE* next;				//指向后继结点的指针
          }DLNODE;
          
        • 图形所示

          在这里插入图片描述

        • 循环单链表

          • 循环单链表:只要将单链表的最后一个结点的指针域指向链表中的第一个结点即可。
        • 循环双链表

          • 循环双链表:将双链表的最后一个结点next的指针域指向链表的第一个结点,并且链表第一个结点的指针域prior指向最后一个结点。
        • 静态链表

          • 借助一维数组实现,数组中的每一个结点含有两个分量:一个是数据元素data,另一个是指针分量,指向当前结点的直接后继在数组中的位置,即下标。
          • 图形所示
            • [外链图片转存失败(img-INQczhkC-1564582507559)(C:\Users\DONG\AppData\Roaming\Typora\typora-user-images\1564581463498.png)]
  3. 线性表的应用

    • 基本操作:增删查改
    • 合并两个链表或者顺序表等。
(三)本章相关代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值