线性表:是N个类型相同数据元素的有限序列,N>0,除第一个元素没有前驱,最后一个元素没有后继之外,其余元素都只有一个前驱和一个后继。记作(a1,a2,...an)如图1,数据元素之间是一对一关系。
图1:线性表的逻辑结构
线性表的特点:
1.同一性:由同类数据元素组成。
2.有穷性:由有限个数据元素组成,表长度为数据元素的个数。
3.有序性:相邻元素之间存在着序偶关系<ai,ai+1>。
线性表抽象数据类型定义
线性表的基本操作应当有创建空表、返回长度信息、插入、删除等操作,其基本的ADT如下:
ADT List:
List(self) #创建一个新表
is_empty(self) #判断self是否是一个空表
len(self) #返回表长度
prepend(self,elem) #在表头插入元素
append(self,elem) #在表尾加入元素
insert(self,elem,i) #在表的位置i处插入元素
del_first(self) #删除第一个元素
def_last(self) #删除最后一个元素
del(self,i) #删除第I个元素
search(self,elem) #查找元素在表中第一次出现的位置
forall(self,op) #对表元素的遍历操作,op操作
序号 | 函数 |
---|---|
1 | len(list) 列表元素个数 |
2 | max(list) 返回列表元素最大值 |
3 | min(list) 返回列表元素最小值 |
4 | list(seq) 将元组转换为列表 |
线性表的顺序存储结构
线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素,使得线性表中在逻辑结构上相邻的数据元素存储在连续的物理存储单元中,即通过数据元素物理存储的连续性来反映数据元素之间逻辑上的相邻关系。
python内部的tuple与list采用的就是顺序表结构,其不同点在于tuple是固定结构,一旦创建就无法进行改动,而list则支持变动操作,具有上述ADT所描述的全部操作,这里不再具体重写类代码,其主要使用命令如下
list1=list([1,2,34,5,6,7])#创建新表
print(list1)
list1.append(9)#在表尾插入元素9
print(list1)
k=len(list1)#返回表的长度
print(k)
list1.insert(0,5)#在第0个位置,插入元素5
print(list1)
e=list1.pop()#返回并删除尾部元素
print(e)
list2=list1[2:]#切片操作
print(list2)
list1.clear()#清空列表
print(list1)
list3=list2.copy()#复制列表
print(list3)
list3.extend(list2)#在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
print(list3)
q=list3.count(34)#统计某个元素在列表中出现的次数
print(q)
w=list3.index(34)#在列表中找出某个值第一个匹配项的索引位置
print(w)
list3.reverse()#反向索引列表
print(list3)
list3.remove(obj)#移除某个项的第一个匹配值
print(list3)
线性表的链式存储
链表是用一组任意的存储单元来存放线性表的结点,这组存储单元可以是连续的,也可以是非连续的,甚至是零散分布在内存的任何位置上。因此,链表中结点的逻辑顺序和物理顺序不一定相同。
结点包括两个域:数据域用来存储结点的值,指针域用来存储数据元素的直接后继的地址(或位置)。线性链表正式通过每个结点的指针域将线性表的n个结点按其逻辑顺序链接在一起的。由于此线性链表的每个结点只有一个next指针域,故将这种链表称为单链表。
图2 单链表的逻辑状态
import copy
#单链表结点类
class LNode:
def __init__(self, elem,next_=None):
self.elem = elem
self.next = next_
#链表位置定位错误
class LinkedListUnderflow(ValueError):
pass
#单链表类的具体实现
class LList:
def __init__(self): #初始化操作
self._head = None
self.num = 0 #num记录结点数
def is_empty(self): #空表判定
return self._head is None
def len(self): #返回表长
return self.num
#定位到链表的第loc个元素
def located(self,loc):
if (loc > self.num or loc < 1):
raise LinkedListUnderflow('in located')
temp = self._head
i = 1
if loc == 1:
return temp
else:
while i < loc:
temp = temp.next
i += 1
return temp
#在链表的第loc个位置添加元素elem
def located_add(self,loc,elem):
temp = self.located(loc)
node = LNode(elem)
if loc == 1:
node.next = self._head
self._head = node
else: