什么是Python中的顺序表


Posted in Python onJune 02, 2020

1、顺序表介绍

顺序表是最简单的一种线性结构,逻辑上相邻的数据在计算机内的存储位置也是相邻的,可以快速定位第几个元素,中间不允许有空,所以插入、删除时需要移动大量元素。顺序表可以分配一段连续的存储空间Maxsize,用elem记录基地址,用length记录实际的元素个数,即顺序表的长度

什么是Python中的顺序表

上图1表示的是顺序表的基本形式,数据元素本身连续存储,每个元素所占的存储单元大小固定相同,元素的下标是其逻辑地址,而元素存储的物理地址(实际内存地址)可以通过存储区的起始地址Loc (e0)加上逻辑地址(第i个元素)与存储单元大小(c)的乘积计算而得,即:Loc(element i) = Loc(e0) + c*i

所以,访问指定元素时无需从头遍历,通过计算便可获得对应地址,其时间复杂度为O(1)。

如果元素的大小不统一,则须采用图2的元素外置的形式,将实际数据元素另行存储,而顺序表中各单元位置保存对应元素的地址信息(即链接)。由于每个链接所需的存储量相同,通过上述公式,可以计算出元素链接的存储位置,而后顺着链接找到实际存储的数据元素。注意,图2中的c不再是数据元素的大小,而是存储一个链接地址所需的存储量,这个量通常很小。

图2这样的顺序表也被称为对实际数据的索引,这是最简单的索引结构。

2、顺序表的结构

什么是Python中的顺序表

一个顺序表的完整信息包括两部分,一部分是表中的元素集合,另一部分是为实现正确操作而需记录的信息,即有关表的整体情况的信息,这部分信息主要包括元素存储区的容量和当前表中已有的元素个数两项。

3、顺序表的两种基本实现方式

什么是Python中的顺序表

1为一体式结构,存储表信息的单元与元素存储区以连续的方式安排在一块存储区里,两部分数据的整体形成一个完整的顺序表对象。一体式结构整体性强,易于管理。但是由于数据元素存储区域是表对象的一部分,顺序表创建后,元素存储区就固定了。

2为分离式结构,表对象里只保存与整个表有关的信息(即容量和元素个数),实际数据元素存放在另一个独立的元素存储区里,通过链接与基本表对象关联。

4、元素存储区替换

一体式结构由于顺序表信息区与数据区连续存储在一起,所以若想更换数据区,则只能整体搬迁,即整个顺序表对象(指存储顺序表的结构信息的区域)改变了。分离式结构若想更换数据区,只需将表信息区中的数据区链接地址更新即可,而该顺序表对象不变。

5、元素存储区扩充

采用分离式结构的顺序表,若将数据区更换为存储空间更大的区域,则可以在不改变表对象的前提下对其数据存储区进行了扩充,所有使用这个表的地方都不必修改。只要程序的运行环境(计算机系统)还有空闲存储,这种表结构就不会因为满了而导致操作无法进行。人们把采用这种技术实现的顺序表称为动态顺序表,因为其容量可以在使用中动态变化。

扩充的两种策略

每次扩充增加固定数目的存储位置,如每次扩充增加10个元素位置,这种策略可称为线性增长。

特点:节省空间,但是扩充操作频繁,操作次数多。

每次扩充容量加倍,如每次扩充增加一倍存储空间。

特点:减少了扩充操作的执行次数,但可能会浪费空间资源。以空间换时间,推荐的方式。

6、顺序表的增删改查操作的Python代码实现

# 创建顺序表class Sequence_Table(): 
 # 初始化
 def __init__(self):
 self.date = [None]*100
 self.length = 0 
 # 判断是否已经满了
 def isFull(self): 
 if self.length>100: 
 print("该顺序表已满,无法添加元素") 
 return 1 
 else: 
 return 0 
 # 按下表索引查找
 def selectByIndex(self,index): 
 if index>=0 and index<=self.length-1: 
 return self.date[index] 
 else: 
 print("你输入的下标不对,请重新输入\n") 
 return 0 
 # 按元素查下标
 def selectByNum(self,num):
 isContain = 0 
 for i in range(0,self.length): 
 if self.date[i] == num:
 isContain = 1 
 print("你要查找的元素下标是%d\n"%i) 
 if isContain == 0: 
 print("没有找你你要的数据") 
 # 追加数据
 def addNum(self,num): 
 if self.isFull() == 0:
 self.date[self.length] = num
 self.length += 1 
 # 打印顺序表
 def printAllNum(self): 
 for i in range(self.length): 
 print("a[%s]=%s"%(i,self.date[i]),end=" ") 
 print("\n") 
 # 按下标插入数据
 def insertNumByIndex(self,num,index): 
 if index<0 or index>self.length: 
 return 0
 self.length += 1 
 for i in range(self.length-1,index,-1):
 temp = self.date[i]
 self.date[i] = self.date[i-1]
 self.date[i-1] = temp
 self.date[index] = num 
 return 1 # 按下标删除数据
 def delectNumByIndex(self,index): 
 if self.length <= 0: 
 print("该顺序表内没有数据,不用删除") 
 for i in range(index,self.length-1):
 temp = self.date[i]
 self.date[i] = self.date[i + 1]
 self.date[i + 1] = temp
 self.date[self.length-1] = 0
 self.length -= 1def main(): # 创建顺序表对象
 seq_t = Sequence_Table() 
 # 插入三个元素
 seq_t.addNum(1)
 seq_t.addNum(2)
 seq_t.addNum(3) 
 # 打印验证 
 seq_t.printAllNum() 
 # 按照索引查找
 num = seq_t.selectByIndex(2) 
 print("你要查找的数据是%d\n" % num) 
 # 按照索引插入数据
 seq_t.insertNumByIndex(4, 1)
 seq_t.printAllNum() 
 # 按照数字查下标
 seq_t.selectByNum(4) 
 #删除数据
 seq_t.delectNumByIndex(1)
 seq_t.printAllNum() 
if __name__ == "__main__":
 main()

运行结果为:

a[0]=1 a[1]=2 a[2]=3
你要查找的数据是3
a[0]=1 a[1]=4 a[2]=2 a[3]=3
你要查找的元素下标是1
a[0]=1 a[1]=2 a[2]=3

7、顺序表的增删改查操作的C语言代码实现

#include<stdio.h>
// 1、定义顺序表的储存结构
typedef struct
{
 //用数组存储线性表中的元素
 int data[100];
 // 顺序表中的元素个数
 int length;
}Sequence_table,*p_Sequence_table;
// 2、顺序表的初始化,
void initSequenceTable(p_Sequence_table T)
{
 // 判断传过来的表是否为空,为空直接退出
 if (T == NULL)
 {
 return;
 }
 // 设置默认长度为0
 T->length = 0;
}
// 3、求顺序表的长度
int lengthOfSequenceTable(p_Sequence_table T)
{
 if (T==NULL)
 {
 return 0;
 }
 return T->length;
}
// 4、判断顺序表是否已满
int isFull(p_Sequence_table T)
{
 if (T->length>=100)
 {
 printf("该顺序表已经装满,无法再添加元素");
 return 1;
 }
 return 0;
}
// 5、按序号查找
int selectSequenceTableByIndex(p_Sequence_table T,int index)
{
 if (index>=0&&index<=T->length-1)
 {
 return T->data[index];
 }
 printf("你输入的序号不对,请重新输入\n");
 return 0;
}
// 6、按内容查找是否存在
void selectSequenceTableByNum(p_Sequence_table T,int num)
{
 int isContain = 0;
 for (int i=0; i<T->length; i++)
 {
 if (T->data[i] == num)
 {
 isContain = 1;
 printf("你要找的元素的下标是:%d\n",i);
 }
 }
 if (isContain == 0)
 {
 printf("没有找到你要的数据\n");
 }
}
// 7、添加元素(在队尾添加)
void addNumber(p_Sequence_table T,int num)
{
 // 顺序表还没有满的时候
 if (isFull(T) == 0)
 {
 T->data[T->length] = num;
 T->length++;
 }
}
// 8、顺序表的遍历
void printAllNumOfSequenceTable(p_Sequence_table T)
{
 for (int i = 0; i<T->length; i++)
 {
 printf("T[%d]=%d ",i,T->data[i]);
 }
 printf("\n");
}
//9、插入操作
int insertNumByIndex(p_Sequence_table T, int num,int index)
{
 if (index<0||index>T->length)
 {
 return 0;
 }
 T->length++;
 for (int i = T->length-1; i>index; i--)
 {
 int temp = T->data[i];
 T->data[i] = T->data[i-1];
 T->data[i-1] = temp;
 }
 T->data[index] = num;
 return 1;
}
// 10、删除元素
void delectNum(p_Sequence_table T,int index)
{
 if (T->length <= 0)
 {
 printf("该顺序表中没有数据,不用删除");
 }
 for (int i = index;i<T->length-1; i++)
 {
 int temp = T->data[i];
 T->data[i] = T->data[i+1];
 T->data[i+1] = temp;
 }
 T->data[T->length-1] = 0;
 T->length--;
}
int main(int argc, const char * argv[]) {
 
 // 创建顺序表的结构体
 Sequence_table seq_t;
 // 初始化
 initSequenceTable(&seq_t);
 // 添加数据
 addNumber(&seq_t, 1);
 addNumber(&seq_t, 2);
 addNumber(&seq_t, 3);
 // 打印验证
 printAllNumOfSequenceTable(&seq_t);
 // 根据索引下标查内容
 int num = selectSequenceTableByIndex(&seq_t, 2);
 printf("你查的数据是:%d\n",num);
 // 插入
 insertNumByIndex(&seq_t, 4, 1);
 printAllNumOfSequenceTable(&seq_t);
 // 根据内容查下标
 selectSequenceTableByNum(&seq_t, 4);
 // 根据下标删除数据
 delectNum(&seq_t, 1);
 printAllNumOfSequenceTable(&seq_t);
 return 0;
}

运行结果为:

T[0]=1 T[1]=2 T[2]=3
你查的数据是:3
T[0]=1 T[1]=4 T[2]=2 T[3]=3
你要找的元素的下标是:1
T[0]=1 T[1]=2 T[2]=3

知识点扩展:

Python中的list和tuple两种类型采用了顺序表的实现技术,具有前面讨论的顺序表的所有性质。

tuple是不可变类型,即不变的顺序表,因此不支持改变其内部状态的任何操作,而其他方面,则与list的性质类似。

list的基本实现技术

Python标准类型list就是一种元素个数可变的线性表,可以加入和删除元素,并在各种操作中维持已有元素的顺序(即保序),而且还具有以下行为特征:

基于下标(位置)的高效元素访问和更新,时间复杂度应该是O(1);

为满足该特征,应该采用顺序表技术,表中元素保存在一块连续的存储区中。

允许任意加入元素,而且在不断加入元素的过程中,表对象的标识(函数id得到的值)不变。

为满足该特征,就必须能更换元素存储区,并且为保证更换存储区时list对象的标识id不变,只能采用分离式实现技术。

在Python的官方实现中,list就是一种采用分离式技术实现的动态顺序表。这就是为什么用list.append(x) (或 list.insert(len(list), x),即尾部插入)比在指定位置插入元素效率高的原因。

在Python的官方实现中,list实现采用了如下的策略:在建立空表(或者很小的表)时,系统分配一块能容纳8个元素的存储区;在执行插入操作(insert或append)时,如果元素存储区满就换一块4倍大的存储区。但如果此时的表已经很大(目前的阀值为50000),则改变策略,采用加一倍的方法。引入这种改变策略的方式,是为了避免出现过多空闲的存储位置。

以上就是什么是Python中的顺序表的详细内容,更多关于Python中顺序表详解的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python中enumerate的用法实例解析
Aug 18 Python
用Python实现一个简单的能够发送带附件的邮件程序的教程
Apr 08 Python
用Python脚本来删除指定容量以上的文件的教程
May 04 Python
Windows下为Python安装Matplotlib模块
Nov 06 Python
python实现识别相似图片小结
Feb 22 Python
利用Python中SocketServer 实现客户端与服务器间非阻塞通信
Dec 15 Python
树莓派动作捕捉抓拍存储图像脚本
Jun 22 Python
Django模型修改及数据迁移实现解析
Aug 01 Python
解决pandas展示数据输出时列名不能对齐的问题
Nov 18 Python
python3 实现调用串口功能
Dec 26 Python
python安装第三方库如xlrd的方法
Oct 31 Python
写一个Python脚本下载哔哩哔哩舞蹈区的所有视频
May 31 Python
opencv 实现特定颜色线条提取与定位操作
Jun 02 #Python
Python爬虫入门有哪些基础知识点
Jun 02 #Python
Python实现进度条和时间预估的示例代码
Jun 02 #Python
python爬虫容易学吗
Jun 02 #Python
基于Python词云分析政府工作报告关键词
Jun 02 #Python
使用OpenCV获取图像某点的颜色值,并设置某点的颜色
Jun 02 #Python
如何利用python web框架做文件流下载的实现示例
Jun 02 #Python
You might like
Re:从零开始的异世界生活 第2季 开播啦
2020/07/24 日漫
php缓存技术介绍
2006/11/25 PHP
Blitz templates 最快的PHP模板引擎
2010/04/06 PHP
php curl的深入解析
2013/06/02 PHP
thinkphp实现多语言功能(语言包)
2014/03/04 PHP
PHP的命令行命令使用指南
2015/08/18 PHP
利用php操作memcache缓存的基础方法示例
2017/08/02 PHP
对setInterval在火狐和chrome切换标签产生奇怪的效果之探索,与解决方案!
2011/10/29 Javascript
基于jQuery的输入框在光标位置插入内容, 并选中
2011/10/29 Javascript
JavaScript的事件绑定(方便不支持js的时候)
2013/10/01 Javascript
删除javascript中注释语句的正则表达式
2014/06/11 Javascript
jQuery圆形统计图开发实例
2015/01/04 Javascript
浅谈JavaScript中指针和地址
2015/07/26 Javascript
不间断循环滚动效果的实例代码(必看篇)
2016/10/08 Javascript
thinkphp标签实现bootsrtap轮播carousel实例代码
2017/02/19 Javascript
Linux CentOS系统下安装node.js与express的方法
2017/04/01 Javascript
vue构建单页面应用实战
2017/04/10 Javascript
Require.JS中的几种define定义方式示例
2017/06/01 Javascript
JS字符串去除连续或全部重复字符的实例
2018/03/08 Javascript
对Angular中单向数据流的深入理解
2018/03/31 Javascript
ios中视频的最后一桢问题解决
2019/05/14 Javascript
Vue js with语句原理及用法解析
2020/09/03 Javascript
在Mac OS系统上安装Python的Pillow库的教程
2015/11/20 Python
Python开发之快速搭建自动回复微信公众号功能
2016/04/22 Python
python 实现将字典dict、列表list中的中文正常显示方法
2018/07/06 Python
python实现flappy bird游戏
2018/12/24 Python
jupyter notebook中美观显示矩阵实例
2020/04/17 Python
python小白学习包管理器pip安装
2020/06/09 Python
Python 解析简单的XML数据
2020/07/24 Python
Python 高效编程技巧分享
2020/09/10 Python
利用css3 translate完美实现表头固定效果
2017/02/28 HTML / CSS
介绍一下Linux内核的排队自旋锁
2014/08/27 面试题
中间件的定义
2016/08/09 面试题
应届优秀本科大学毕业生自我鉴定
2014/01/21 职场文书
深度好文:50条没人告诉你的人生经验,句句精辟
2019/08/22 职场文书
Oracle 触发器trigger使用案例
2022/02/24 Oracle