什么是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运行的17个时新手常见错误小结
Aug 07 Python
python实现zencart产品数据导入到magento(python导入数据)
Apr 03 Python
Python算法之栈(stack)的实现
Aug 18 Python
Python与shell的3种交互方式介绍
Apr 11 Python
Python实现输出程序执行进度百分比的方法
Sep 16 Python
Python算法之图的遍历
Nov 16 Python
python中实现字符串翻转的方法
Jul 11 Python
使用OpenCV实现仿射变换—旋转功能
Aug 29 Python
python3中的logging记录日志实现过程及封装成类的操作
May 12 Python
Python使用itcaht库实现微信自动收发消息功能
Jul 13 Python
Sentry错误日志监控使用方法解析
Nov 12 Python
Python下opencv库的安装过程及问题汇总
Jun 11 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
dedecms模版制作使用方法
2007/04/03 PHP
JavaScript 语法集锦 脚本之家基础推荐
2009/11/15 Javascript
把jQuery的类、插件封装成seajs的模块的方法
2014/03/12 Javascript
jquery操作select元素和option的实例代码
2016/02/03 Javascript
vue结合Echarts实现点击高亮效果的示例
2018/03/17 Javascript
vue用Object.defineProperty手写一个简单的双向绑定的示例
2018/07/09 Javascript
vue webpack打包后图片路径错误的完美解决方法
2018/12/07 Javascript
fetch 如何实现请求数据
2018/12/20 Javascript
Vue中axios的封装(报错、鉴权、跳转、拦截、提示)
2019/08/20 Javascript
Node.js 在本地生成日志文件的方法
2020/02/07 Javascript
JS FormData对象使用方法实例详解
2020/02/12 Javascript
python解析文件示例
2014/01/23 Python
基于Python函数的作用域规则和闭包(详解)
2017/11/29 Python
Python3.6安装及引入Requests库的实现方法
2018/01/24 Python
Pandas中把dataframe转成array的方法
2018/04/13 Python
matplotlib subplots 设置总图的标题方法
2018/05/25 Python
python字典嵌套字典的情况下找到某个key的value详解
2019/07/10 Python
Python二维数组实现求出3*3矩阵对角线元素的和示例
2019/11/29 Python
python 读取更新中的log 或其它文本方式
2019/12/24 Python
python 实现简单的FTP程序
2019/12/27 Python
Numpy 理解ndarray对象的示例代码
2020/04/03 Python
Python 抓取数据存储到Redis中的操作
2020/07/16 Python
无惧面试,带你搞懂python 装饰器
2020/08/17 Python
python 实现数据库中数据添加、查询与更新的示例代码
2020/12/07 Python
CSS3 text-shadow实现文字阴影效果
2016/02/24 HTML / CSS
美国在线珠宝商店:SZUL
2017/02/11 全球购物
大课间活动制度
2014/01/18 职场文书
丧事主持词大全
2014/04/02 职场文书
政府法律服务方案
2014/06/14 职场文书
爱心捐书活动总结
2014/07/05 职场文书
2015年社会实践个人总结
2015/03/06 职场文书
酒店前台接待岗位职责
2015/04/02 职场文书
酒店收银员岗位职责
2015/04/07 职场文书
MySQL命令无法输入中文问题的解决方式
2021/08/30 MySQL
SQL Server表分区降低运维和维护成本
2022/04/08 SQL Server
html中相对位置与绝对位置的具体使用
2022/05/15 HTML / CSS