什么是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下的subprocess模块的入门指引
Apr 16 Python
使用Python中的tkinter模块作图的方法
Feb 07 Python
tensorflow入门之训练简单的神经网络方法
Feb 26 Python
Python将DataFrame的某一列作为index的方法
Apr 08 Python
利用Python将每日一句定时推送至微信的实现方法
Aug 13 Python
Python使用mongodb保存爬取豆瓣电影的数据过程解析
Aug 14 Python
Python流程控制 if else实现解析
Sep 02 Python
如何在mac环境中用python处理protobuf
Dec 25 Python
python 实现按对象传值
Dec 26 Python
在jupyter notebook中调用.ipynb文件方式
Apr 14 Python
Keras loss函数剖析
Jul 06 Python
通过代码实例了解Python sys模块
Sep 14 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
一个简易需要注册的留言版程序
2006/10/09 PHP
PHPExcel 修改已存在Excel的方法
2018/05/03 PHP
js中判断控件是否存在
2010/08/25 Javascript
script标签的 charset 属性使用说明
2010/12/04 Javascript
javascript 判断字符串是否包含某字符串及indexOf使用示例
2013/10/18 Javascript
iframe调用父页面函数示例详解
2014/07/17 Javascript
简化版手机端照片预览组件
2015/04/13 Javascript
Bootstrap中的Dropdown下拉菜单更改为悬停(hover)触发
2016/08/31 Javascript
详解使用Vue.Js结合Jquery Ajax加载数据的两种方式
2017/01/10 Javascript
layui框架与SSM前后台交互的方法
2019/09/12 Javascript
微信小程序自定义弹出层效果
2020/05/26 Javascript
vue集成openlayers加载geojson并实现点击弹窗教程
2020/09/24 Javascript
树莓派中python获取GY-85九轴模块信息示例
2013/12/05 Python
Python写的Socks5协议代理服务器
2014/08/06 Python
Django 导出 Excel 代码的实例详解
2017/08/11 Python
Python实现变量数值交换及判断数组是否含有某个元素的方法
2017/09/18 Python
Python分支结构(switch)操作简介
2018/01/17 Python
Python批量提取PDF文件中文本的脚本
2018/03/14 Python
python如何统计序列中元素
2020/07/31 Python
Python产生Gnuplot绘图数据的方法
2018/11/09 Python
Python编写带选项的命令行程序方法
2019/08/13 Python
python 调试冷知识(小结)
2019/11/11 Python
Django使用消息提示简单的弹出个对话框实例
2019/11/15 Python
Python 内置函数globals()和locals()对比详解
2019/12/23 Python
python使用Thread的setDaemon启动后台线程教程
2020/04/25 Python
带你认识HTML5中的WebSocket
2015/05/22 HTML / CSS
荷兰睡眠专家:Beter Bed
2020/11/23 全球购物
毕业生找工作推荐信
2013/11/21 职场文书
经营目标管理责任书
2014/07/25 职场文书
企业挂职心得体会
2014/09/10 职场文书
2015年个人思想总结
2015/03/09 职场文书
签字仪式主持词
2015/07/03 职场文书
《鲸》教学反思
2016/02/23 职场文书
go:垃圾回收GC触发条件详解
2021/04/24 Golang
python 进阶学习之python装饰器小结
2021/09/04 Python
MySQL读取JSON转换的方式
2022/03/18 MySQL