【链表5】线性表(List)简介

文 /Edward

  结构体数组与线性表A

前面我们使用结构体数组设计出了类似于“表(Table)“数据结构的存储序列,它以整个定长度的结构体数组为单位,并且以每个结构体数组中的元素来存放具体的数据对象。再深入思考一下,前面我们讲过数组中每个元素的内存地址是顺序的,那是不是就是这个表就是线性表呢?其实不是,这种用结构体数组组成的类似于表格的存储单元,他不具备一个”表“数据结构的完整特征,即动态地增,减,删,查。而在C语言数据结构中,有一种专门的数据结构叫做”线性表“。

”线性表“和我们前面所讲述的结构体数组表之间唯一的区别就是,”线性表“可以动态地增,减,删,查这个表中的所有表项,也即我们所谓的表”节点“。好了,现在问题变得非常简单了,我们可以将之前讲述的结构体数组表类比于一个普通的数组,那么线性表相比于结构体数组表就类似要解决的问题就是,动态地去改变这个”数组“的长度。

  动态改变“数组“长度

我们前面讲过了,一个数组的长度是在这个数组被定义完成之后所决定的,因为这是牵扯到内存分配的问题,因此我们根本无法去修改这个这个数组的长度,怎么现在又要来改变它的长度了呢?这个问题其实也很好解决,我们再来回顾一下数据的内存排列,如图1所示。

图1 数组内存分布

图1中的数组内存分布相信大家都非常简单就可以看懂,就让我们再来回顾一下。假设这个数组的类型是char类型的,当我们定义好了这个数组之后,这个数组名在C语言中其实就是代表着这个数组存放的首地址,也即第一个数组元素的地址。而第二个元素其实是在这个数组的首地址基础上偏移一个数组类型的长度(如char类型数组偏移1,int类型偏移2或者4)。

因此,我们只要知道两个信息就可以在一个数组里面找到任何一个元素了,这两个信息就是这个数组的起始地址和偏移量。

我们再来深层次地思考一下,数组的本质其实就是将多个同一类型的变量打包到一起去,便于我们编程和检索。而如果我们知道数组的起始地址和偏移量这两个维度的信息,那么它本质上是不是数组其实都无所谓,因为其最终表达的含义也跟数组差不多。

所以实现一个动态长度的数组就变得很简单了,我们只需要定义一个结构体用来存储用这个数组的起始地址和长度。注意,这个长度是我们为这个表增加的节点数,而这个起始地址存储着我们使用malloc函数为我们指定长度的数组申请好内存之后的返回值。

因此,我们就可以使用如图2中所示的代码来初始化这个线性表的第一个节点,即初始节点。

图2 创建初始节点

好了,现在一个不定长度的数组被创建完成了,只要我们每次配分数组时,指定这个数组的长度,程序就会按照我们的要求为我们创建一个新的指定长度的数组了。此时数组分配好的内存示意如图3所示。

图3 线性表创建好初始节点

创建完成表之后,接下来要做的就是对这个表里面插入新的数据了,即相当于对数组元素进行赋值。赋值的时候,我们前面讲数组的时候也说了,对于数组某一项赋值也可以使用“基地址+偏移量”的形式。添加新的数据项的代码如图4所示。

图4 写入和读出数据项

以上就是线性表的一些基本知识,我们这里只是将其作为动态数组的形式来读写这个线性表的。事实上,这个线性表和结构体数组比起来改善好不到哪里去,因为它的数据项也只有每次在初始化的时候改变。而且如果在对线性表插入数据的时候,需要将数组内所有的数据移位,特别占用时间。因此,这种线性表在我们日常的应用中基本不会用到,我们就不对其进行深入学习了。

本文源码

#include<stdio.h>#include<stdlib.h>#define SUCCESS 0#define FAIL 1typedef int ListNode_t;typedef struct{ ListNode_t *ListNode; //存放线性表的初始地址int length; //存放线性表当前存放数据的长度} List_t;
/**@brief: 初始化线性表,即分配初始地址和申请指定长度的内存*/int InitList(List_t *List, int legnth){int RetVal = SUCCESS; List->ListNode = NULL; List->ListNode = (ListNode_t *)malloc(sizeof(ListNode_t) * legnth);if(List->ListNode == NULL) { RetVal = FAIL; } List->length = 0;return RetVal;}
/**@brief: 在线性表的某个索引赋值*@Para:List_t *List --- 表首地址 int index --- 写入的索引 ListNode_t data --- 写入的数据 int ArrayMaxLen --- 最大的数组长度,这个可以使用define定义的符号代替*/int ListAddElem(List_t *List, int index, ListNode_t data, int ArrayMaxLen){int RetVal = SUCCESS;if(index < 0 || index >= ArrayMaxLen) { RetVal = FAIL; } *(List->ListNode + index) = data; List->length ++;return RetVal;}/**@brief: 读取线性表的某个索引中的数据*@Para:List_t *List --- 表首地址 int index --- 写入的索引 ListNode_t data --- 写入的数据 int ArrayMaxLen --- 最大的数组长度,这个可以使用define定义的符号代替*/ListNode_t ListReadElem(List_t *List, int index, int ArrayMaxLen){ ListNode_t RetVal = 0;if(index < 0 || index >= ArrayMaxLen) { RetVal = FAIL; } RetVal = *(List->ListNode + index);return RetVal;}int main(void){ List_t NameList; ListNode_t Elem;int ArrayLength = 5;if(InitList(&NameList, ArrayLength) == FAIL) {printf("Create list fail"); }else {printf("Create list successfully, address is %#x\n", NameList.ListNode); } ListAddElem(&NameList, 0, 14, 5); Elem = ListReadElem(&NameList, 0, 5);printf("The element is %d\n", Elem);return 0;}


(0)

相关推荐

  • PHP数据结构-散列表查找

    散列表查找 上篇文章的查找是不是有意犹未尽的感觉呢?因为我们是真真正正地接触到了时间复杂度的优化.从线性查找的 O(n) 直接优化到了折半查找的 O(logN) ,绝对是一个质的飞跃.但是,我们的折半 ...

  • ​LeetCode刷题实战23:合并K个升序链表

    算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试.所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 ! 今天和大家 ...

  • 初赛第二课习题

    您的姓名:* 111.算法是指( )* A.为解决问题而编写的计算机程序 B.为解决问题而采取的方法与步骤 C.为解决问题而需要采用的计算机语言 D.为解决问题而采用的计算方法 112.设栈S的初始状 ...

  • 双指针技巧秒杀四道数组/链表题目

    26.删除排序数组中的重复项 83.删除排序链表中的重复元素 27.移除元素 283.移动零 ------------ 我们知道对于数组来说,在尾部插入.删除元素是比较高效的,时间复杂度是 O(1), ...

  • PHP数据结构-线性表?顺序表?链表?别再傻傻分不清楚

    线性表?顺序表?链表?别再傻傻分不清楚 遵从所有教材以及各类数据结构相关的书书籍,我们先从线性表开始入门.今天这篇文章更偏概念,是关于有线性表的一个知识点的汇总. 上文说过,物理结构是用于确定数据以何 ...

  • 【数据结构笔记】顺序表——静态分配

    顺序表是线性表的一种存储结构. 什么是线性表? 线性表是一种常用的数据结构.其数据元素之间在逻辑上具有"一对一"的关系.所谓的"一对一",就是除了第一个和最后一 ...

  • 【链表5】<最新>线性表(List)简介

    文 /Edward   结构体数组与线性表A 前面我们使用结构体数组设计出了类似于"表(Table)"数据结构的存储序列,它以整个定长度的结构体数组为单位,并且以每个结构体数组中的 ...

  • 【攻略】阿布赞末日前兆最新牌表及换备

    阿布赞末日前兆是最近一个新流行起来的约力昂套牌.因为有很多生物去除加上结算就赢的神秘通牒,相比于白绿和白蓝的云移版本打现在最流行的蓝黑浪客会好打很多.套牌加入黑色放变节祝福和神秘通牒后,在约力昂内战也 ...

  • 今日万智——GP与SCG的最新牌表

    继续总结周末的比赛并搬运套牌 昨天晚上在GP直播开始前举行的2019年团队决赛冥途求生超前团队轮抓上,Ultimate Guard 战队(简称UG)的第一支小队 [ Paul Rietzl, Matt ...

  • 【收藏】个人独资、合伙企业个人所得税最新税率表

    2018 年 10 月 1 日起新个人生产经营所得税(核定征收)算法如下: 累了乏了,上约单约个按摩放松一下 广告 企业应纳所得税额=应纳税所得额*适用分级税率-速算扣除额. 其中:应纳税所得额=收入 ...

  • 我国台湾省2020年最新行政区划表。辖六...

    我国台湾省2020年最新行政区划表.辖六个地级市(台湾省叫直辖市),三个县级市,十三个县(包含福建省的金门县和连江县). 辖台北市,新北市,桃园市,台中市,台南市,高雄市.(地级市) 基隆市,新竹市, ...

  • 【思维导图】增值税知识纲要(2021.5.25更新) 最新税率表

    2021.4.1  根据<财政部 税务总局关于明确增值税小规模纳税人免征增值税政策的公告>(财政部 税务总局公告2021年第11号)和<国家税务总局关于小规模纳税人免征增值税征管问题 ...

  • 【文库精选】增值税的优惠政策汇总及最新税率表、征收率表

    ◇增值税起征点的适用范围 ㈠"从事小额零星经营业务的个人"的起征点(只限小规模纳税人纳税的个体工商户和其他个人.不适用于登记为一般纳税人的个体工商户) (1)销售货物的,为月销售额 ...

  • 收藏:建筑企业最新进项税额抵扣手册及最新税率表

    2021年最新建筑业增值税进项税额抵扣手册 进项不得抵扣的情况  <财政部 国家税务总局关于全面推开营业税改征增值税试点的通知>(财税[2016]36号)文件附件1第二十七条规定,下列项目 ...