什么是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中的__init__和__new__
Mar 12 Python
Python threading多线程编程实例
Sep 18 Python
关于Python中异常(Exception)的汇总
Jan 18 Python
详解如何在Apache中运行Python WSGI应用
Jan 02 Python
解决Django生产环境无法加载静态文件问题的解决
Apr 23 Python
python flask几分钟实现web服务的例子
Jul 26 Python
详解基于python的多张不同宽高图片拼接成大图
Sep 26 Python
python自动化实现登录获取图片验证码功能
Nov 20 Python
Python内置方法实现字符串的秘钥加解密(推荐)
Dec 09 Python
Jupyter notebook如何修改平台字体
May 13 Python
学python爬虫能做什么
Jul 29 Python
关于探究python中sys.argv时遇到的问题详解
Feb 23 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
php设计模式 Delegation(委托模式)
2011/06/26 PHP
解析php开发中的中文编码问题
2013/08/08 PHP
PHP 99乘法表的几种实现代码
2020/10/13 PHP
JavaScript 学习笔记 Black.Caffeine 09.11.28
2009/11/30 Javascript
JavaScript高级程序设计(第3版)学习笔记13 ECMAScript5新特性
2012/10/11 Javascript
js函数调用的方式
2014/05/06 Javascript
根据输入邮箱号跳转到相应登录地址的解决方法
2016/12/13 Javascript
bootstrap vue.js实现tab效果
2017/02/07 Javascript
layui使用button按钮 点击出现弹层 弹层中加载表单的实例
2019/09/04 Javascript
layui富文本编辑器前端无法取值的解决方法
2019/09/18 Javascript
jQuery--遍历操作实例小结【后代、同胞及过滤】
2020/05/22 jQuery
基于原生js实现判断元素是否有指定class名
2020/07/11 Javascript
vue v-on:click传递动态参数的步骤
2020/09/11 Javascript
Openlayers实现点闪烁扩散效果
2020/09/24 Javascript
vue+springboot+element+vue-resource实现文件上传教程
2020/10/21 Javascript
[03:18]DOTA2亚洲邀请赛小组赛第一日 RECAP赛事回顾
2015/01/30 DOTA
使用cx_freeze把python打包exe示例
2014/01/24 Python
python中字典dict常用操作方法实例总结
2015/04/04 Python
浅析Python中signal包的使用
2015/11/13 Python
python机器学习理论与实战(一)K近邻法
2021/01/28 Python
Python3实现的画图及加载图片动画效果示例
2018/01/19 Python
python读取txt文件,去掉空格计算每行长度的方法
2018/12/20 Python
10 行Python 代码实现 AI 目标检测技术【推荐】
2019/06/14 Python
基于Python的Post请求数据爬取的方法详解
2019/06/14 Python
python中property属性的介绍及其应用详解
2019/08/29 Python
python实现滑雪游戏
2020/02/22 Python
python合并多个excel文件的示例
2020/09/23 Python
Python classmethod装饰器原理及用法解析
2020/10/17 Python
纯CSS3编写的的精美动画进度条(无flash/无图像/无脚本/附源码)
2013/01/07 HTML / CSS
TripAdvisor印尼站:全球领先的旅游网站
2018/03/15 全球购物
常用UNIX 命令(Linux的常用命令)
2015/12/26 面试题
珍珠奶茶店创业计划书
2014/01/11 职场文书
个人对照检查材料
2014/02/12 职场文书
创建卫生先进单位实施方案
2014/03/10 职场文书
公司董事长助理工作职责
2014/07/12 职场文书
2016年小学“公民道德宣传日”活动总结
2016/04/01 职场文书