超详细讲解线性表和顺序表!!
创始人
2024-05-25 23:49:03
0

超详细讲解线性表和顺序表!!

  • 线性表
  • 顺序表
    • 顺序表的概念及结构
      • 静态顺序表
      • 动态顺序表
    • 顺序表接口实现
      • 1、创建
      • 2、初始化
      • 3、扩容
      • 4、尾插
      • 5、打印
      • 6、销毁
      • 7、尾删
      • 8、头插
      • 9、头删
      • 10、插入任意位置
      • 11、删除任意位置
      • 12、查找
      • 13、修改

线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储
地址的计算:
线性表中第一个元素的存储地址(基地址)和表中每个元素所占存储单元的多少,就可以计算出线性表中任意一个数据元素的存储地址,从而实现对顺序表中数据元素的随机存取。
设线性表中有n个元素,每个元素占k个单元,第一个元素的地址为Loc(a_1),则第i个元素的地址Loc(a_i):Loc(a_i)=Loc(a_1)+(i-1)*k

顺序表

顺序表的概念及结构

顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。
顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
在这里插入图片描述
顺序表一般可以分为:静态顺序表与动态顺序表。

静态顺序表

静态顺序表:使用定长数组存储元素。
在这里插入图片描述
静态顺序表从某种意义上来说就是数组

如果数组空间满了就无法继续插入。
无法很好地确定要给定的内存空间,大了浪费空间,小了空间不足。

静态顺序表的大小在编译时确定,对静态顺序表的删除和插入是对其元素进行,而不是其存储空间的删除和插入,因此静态顺序表的大小在进行删除和插入操作后不会改变。
对于静态顺序表的查找,若按序号查找,则时间复杂度为O(1)。若按值查找,则需要将待查元素与表中每一个元素进行比较,直到找到或者遍历整个数组却找不到元素,此操作的时间复杂度为O(N)。

动态顺序表

在这里插入图片描述

顺序表接口实现

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。

void SLInit(SL* ps);//名字简写           初始化
void SLPushBack(SL* ps, SLDatatype x);  //尾插
void SLPopBack(SL* ps);                 //尾删
void SLPushFront(SL* ps, SLDatatype x); //头插
void SLPopFront(SL* ps);                //头删
void SLPrit(SL* ps);                    //打印
void SLDestory(SL* ps);                 //释放
void SLCheckCapacity(SL* ps);           //检查容量-扩容
void SLInsert(SL* ps, int pos, SLDatatype x);//任意位置插入
void SLErase(SL* ps, int pos);          //任意位置删除
int SLFind(SL* ps, SLDatatype x);      //查找
void SLModify(SL* ps,int pos, SLDatatype x);    //修改

在此之前,明白何为接口函数:
接口函数就是某个模块写了(主要)给其它模块用的函数,可以实现隐藏信息,封装等,数据进行操作时进行调用的函数,通过调用数据结构的接口帮助你完成一系列操作

1、创建

因为是一个比较大的板块,在一开始创建时尽量分开不同板块编写。
在这里插入图片描述

#pragma once
#include 
#include 
#include //#define N 200
typedef int SLDatatype;
typedef struct SeqList
{SLDatatype* a;//指向动态数组指针int size;       //数据个数int capacity;  //容量-空间大小
}SL;

使用 typedef 定义一个新的数据类型,这里我们把它取名为 SLDataType(顺序表数据类型)。

2、初始化

#include "SeqList.h"//初始化函数
void SLInit(SL* ps)
{ps->a= NULL;ps->size = ps->capacity= 0;
}

3、扩容

插入元素的时候理所应当需要考虑插入元素时空间是否足够,如果空间不够,则使用realloc函数扩容。(realloc函数在一开始没空间申请空间时等作用于malloc函数的作用)

//检查容量-扩容
void SLCheckCapacity(SL* ps)
{if (ps->size == ps->capacity){int newcapacitv = ps->capacity == 0 ? 4 : ps->capacity * 2;SLDatatype* tmp = (SLDatatype*)realloc(ps->a, newcapacitv * sizeof(SLDatatype));if (tmp == NULL){perror("relloc:");exit(-1);//结束程序}ps->a = tmp;ps->capacity = newcapacitv;}
}

4、尾插

void SLPushBack(SL* ps, SLDatatype x)
{SLCheckCapacity(ps);//检查容量空间ps -> a[ps->size] = x;ps->size++;
}

尾插有三种情况:
① 第一种情况是顺序表压根就没有空间。
② 第二种情况就是我们创建的 capacity 空间满了。
③ 第三种情况是空间足够,直接插入数据即可。

5、打印

打印我们表中所存放的函数。

//打印函数
void SLPrit(SL* ps)
{for (int i = 0; i < ps->size; i++){printf("%d ", ps->a[i]);}printf("\n");
}

6、销毁

不销毁会存在内存泄漏的风险。

void SLDestory(SL* ps)//动态开辟的内存越界使用有时
{                     //有时要在free的时候才能检查出来。if (ps->a){free(ps->a);ps->a = NULL;ps->size = ps->capacity = 0;}
}

7、尾删

删除最后一个元素。只需要元素数量–就好,无法访问最后一个元素那么它便是无效的数据。

void SLPopBack(SL* ps)
{assert(ps->size);ps->size--;
}

当然,包括尾删以及其他步骤,我们都必须要注意越界访问的问题。比如尾删步骤中,如果内存中一个元素都没有了,size有可能减到-1的位置上而出现错误,需要断言一下。
当然,温柔的检查以及暴力的检查读者们喜欢哪个就全取决于自己了。

// 温柔的检查if (ps->size == 0){return;}// 暴力的检查assert(ps->size > 0);//ps->a[ps->size - 1] = 0;ps->size--;
}

8、头插

将数组内容整体后移,就可以在最前面出现一个空的位置。
首先创建一个 end 变量用来指向要移动的数据,因为指向的是数据的下标,所以是 size 要减 1 。随后进入 while 循环,如果 end >= 0 说明还没有移动完,就会进入循环。循环体内利用下标,进行向后移动操作,移动结束后再 end-- ,进行下一个数据的向后移动。挪动数据成功后,就可以插入了。此时顺序表第一个位置就被腾出来了,就可以在下标0位置插入欲插入的数据 x 了。最后size++ 。

void SLPushFront(SL* ps, SLDatatype x)
{SLCheckCapacity(ps);//从后向前挪动数据int end = ps->size - 1;while (end >= 0){ps->a[end + 1] = ps->a[end];end--;}ps->a[0] = x;ps ->size++;
}

9、头删

思路和头插类似。

//头删
void SLPopFront(SL* ps)
{assert(ps->size);int begin = 1;while (begin < ps->size){ps->a[begin-1] = ps->a[begin];begin++;}ps->size--;
}

10、插入任意位置

 
//任意插入
void SLInsert(SL* ps, int pos, SLDatatype x)
{assert(ps);//检查我们要插入的位置assert(pos >= 0 && pos <=ps->size);SLCheckCapacity(ps);int end = ps->size - 1;while (end >= pos){ps->a[end + 1] = ps->a[end];end--;}ps->a[pos] = x;ps->size++;
}

11、删除任意位置

删除指定位置的数据,我们仍然要限制 pos 的位置。限制条件部分和 SeqListInsert 不同的是,因为 psl->size 这个位置没有效数据,所以删除的位置不能是 psl->size!
任意位置删除的函数可以替代头删和尾删。

//任意删除
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);//注意边界的处理/*int begin = pos;while (begin < ps->size - 1){ps->a[begin] = ps->a[begin + 1];begin++;}*/int begin = pos + 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];begin++;}ps->size--;
}

12、查找

//查找
int SLFind(SL* ps, SLDatatype x)
{assert(ps);for (int i = 0; i <= ps->size; i++){if (ps->a[i] == x)return i;}return -1;}

13、修改

//修改
void SLModify(SL* ps, int pos, SLDatatype x)  
{assert(ps);assert(pos >= 0 && pos < ps->size);ps->a[pos] = x;}

相关内容

热门资讯

求经典台词和经典旁白 求经典台词和经典旁白谁有霹雳布袋戏里的经典对白和经典旁白啊?朋友,你尝过失去的滋味吗? 很多人在即将...
小王子第二章主要内容概括 小王子第二章主要内容概括小王子第二章主要内容概括小王子第二章主要内容概括
爱情睡醒了第15集里刘小贝和项... 爱情睡醒了第15集里刘小贝和项天骐跳舞时唱的那首歌是什么谢谢开始找舞伴的时候是林俊杰的《背对背拥抱》...
世界是什么?世界是什么概念?可... 世界是什么?世界是什么概念?可以干什么?物质的和意识的 除了我们生活的地方 比方说山 河 公路 ...
全职猎人中小杰和奇牙拿一集被抓 全职猎人中小杰和奇牙拿一集被抓动画片是第五十九集,五十八集被发现,五十九被带回基地,六十逃走
“不周山”意思是什么 “不周山”意思是什么快快快快......一座山,神话里被共工撞倒了。
《揭秘》一元一分15张跑得快群... 一元一分麻将群加群主微【ab120590】【tj525555】 【mj120590】等风也等你。喜欢...
玩家必看手机正规红中麻将群@2... 好运连连,全网推荐:(ab120590)(mj120590)【tj525555】-Q号:(QQ443...
始作俑者15张跑的快群@24小... 微信一元麻将群群主微【ab120590】 【tj525555】【mj120590】一元一分群内结算,...
《重大通知》24小时一元红中麻... 加V【ab120590】【tj525555】【mj120590】红中癞子、跑得快,等等,加不上微信就...
盘点一下正规一块红中麻将群@2... 一元一分麻将群加群主微:微【ab120590】 【mj120590】【tj525555】喜欢手机上打...
(免押金)上下分一元一分麻将群... 微【ab120590】 【mj120590】【tj525555】专业麻将群三年房费全网最低,APP苹...
[解读]正规红中麻将跑的快@群... 微信一元麻将群群主微【ab120590】 【tj525555】【mj120590】一元一分群内结算,...
《普及一下》全天24小时红中... 微【ab120590】 【mj120590】【tj525555】专业麻将群三年房费全网最低,APP苹...
优酷视频一元一分正规红中麻将... 好运连连,全网推荐:(ab120590)(mj120590)【tj525555】-Q号:(QQ443...
《火爆》加入附近红中麻将群@(... 群主微【ab120590】 【mj120590】【tj525555】免带押进群,群内跑包包赔支持验证...
《字节跳动》哪里有一元一分红中... 1.进群方式-[ab120590]或者《mj120590》【tj525555】--QQ(QQ4434...
全网普及红中癞子麻将群@202... 好运连连,全网推荐:(ab120590)(mj120590)【tj525555】-Q号:(QQ443...
「独家解读」一元一分麻将群哪里... 1.进群方式《ab120590》或者《mj120590》《tj525555》--QQ(4434063...
通知24小时不熄火跑的快群@2... 1.进群方式《ab120590》或者《mj120590》《tj525555》--QQ(4434063...