数据结构分为逻辑结构和物理结构
1)逻辑结构分为集合结构、线性结构、树形结构和图形结构四大类。
2)物理结构分为顺序存储结构和链式存储结构。
线性表
线性表是逻辑结构中线性结构的一种,那么线性表当然也有物理结构,也就是说,线性表有两种,分别是顺序结构的线性表(叫做顺序表)和链式结构的线性表(叫做链表)。
顺序表
顺序表就是在内存中找个初始地址,然后通过占位的形式,把一定的内存空间给占了,然后把相同数据类型的数据元素依次放在这块空地中。注意,这块物理内存的地址空间是连续的。
比如python中声明一个整数i,在32位系统中整数i在内存中占4字节,那么系统就会在内存中为这个整型变量分配一个长度为8个字节的连续的地址空间,然后把这个i的二进制形式从高地址向低地址存储,长度不足时候,最高位用0补齐。
顺序表的三个属性:
1.存储空间的起始位置。
2.线性表的最大存储容量。
3.线性表的当前长度。
顺序表操作时间复杂度:
在存、读取数据时,不管是在哪个位置,时间复杂度都是O(1)
而在插入或者删除时,时间复杂度都是O(n)
这也就是线性表的顺序存储结构比较适合存取数据,不适合经常插入和删除数据的应用
顺序表的两种实现形式
一体式结构:
存储表信息的单元和元素存储区以连续的方式安排在一块存储区里
分离式结构:
表对象只保存与整个表有关的信息(即容量和原始个数),实际数据元素存放在另一个独立的元素存储区,通过链接与基本表对象关联。
链表
我们思考为什么顺序表当插入和删除时,就要移动大量的元素?原因就在于相邻两元素的存储位置也具有邻居关系,它们在内存中的位置是紧挨着的,中间没有间隙,当然就无法快速插入和删除。
线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素,这组存储单元可以存在内存中未被占用的任意位置。
链式存储结构的线性表由一个或者多个结点(Node)组成。每个节点内部又分为数据域和指针域(链)。数据域存储了数据元素的信息。指针域存储了当前结点指向的直接后继的指针地址。因为每个结点只包含一个指针域,所以叫做单链表。顾名思义,当然还有双链表。
和单链表一样,双链表也是由节点组成,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
- 单向链表的实现
#节点类
class Node(object):
def __init__(self, elem):
self.elem = elem
self.next = None
#单链表类
class LinkList(object):
def __init__(self,node = None):
self.__head = node
#链表是否为空
def is_empty(self):
return self.__head == None
#链表长度
def length(self):
#cur游标,用来移动遍历节点
cur = self.__head
#count来记录数量
while cur != None:
count += 1
cur = cur.next
return count
#遍历整个链表
def travel(self):
cur = self.__head
while cur != None:
print(cur.elem, end = “ “)
cur = cur.next
print (“”)
#链表头部添加元素,头插法
def add(self, item):
node = Node(item)
node.next = self.__head
self.__head = node
#链表尾部添加元素,尾插法
def append(self, item):
node = Node(item)
cur = self.__head
while cur != None:
cur = cur.next
cur = node
#指定位置插入元素
def insert(self, pos, item):
if pos <=0:
self.append(item)
elif pos > (self.length – 1):
self.append(item)
else:
pre = self.__head
count = 0
while count < (pos – 1):
count +=1
pre = pre.next
#当循环退出后,pre 指向pos-1位置
node = Node(item)
node.next = pre.next
pre.next = node
#删除节点
def remove(self, item):
cur = self.__head
if cur.elem == item: #先判断是否是头节点
self.__head = cur.next
else:
while cur != None:
if cur.next.elem == item:
cur.next = cur.next.next
else:
cur = cur.next
#查找节点是否存在
cur = self.__head
while cur != None:
if cur.elem == item:
return True
else:
cur = cur.next
return False
if __name__ == “__main__”:
ll = SingleLinkList()
顺序表与链表的对比
操作 |
链表 |
顺序表 |
访问元素 |
O(n) |
O(1) |
在头部插入/删除 |
O(1) |
O(n) |
在尾部插入/删除 |
O(n) |
O(1) |
在中间插入/删除 |
O(n) |
O(n) |