数据结构1-1. 链表(Linked List)
一、链表简介
链表是一种逻辑顺序上连续、存储空间上不连续、不顺序的线性数据结构,其逻辑顺序由链表的指针依次链接实现。
Head Tail

链表由一个个结点组成,每个节点由存储数据的数据域和存储指向下一结点指针的指针域组成。
定义链表的结点:
1 class Node:
2 def __init__(self, data, next=None):
3 self.data = data
4 self.next = next
链表的优点是不需要预先知道数据的大小,可以充分利用计算机内存空间,但其扩展的指针域增大了空间开销。与数组不同,我们无法在常量时间内访问单链表中的随机元素。 如果我们想要获得第 i 个元素,我们必须从头结点逐个遍历。 我们按索引来访问元素平均要花费 O(N) 时间,其中 N 是链表的长度。
二、链表的类型
根据链表的结构,链表的类型有单向链表、双向链表和循环链表等。
- 单向链表

单向链表又叫单链表,是链表中最简单的形式,每个结点的指针都依次指向下一个结点,最后一个结点的指针指向一个空置Null,单向链表只可向一个方向遍历。
- 双向链表
双向链表比单向链表更加复杂,它的每个结点有两个指针next 和 prev,next指向下一个结点,当前结点为最后一个结点时,指向空值;prev指向上一个结点,当前结点为第一个结点时,指向空值。

- 循环链表
循环链表为单链表的变种,链表的最后一个结点指向链表的头结点,形成一个循环。
三、链表的操作
- 添加操作 - 单链表
一句话:先让新来的结点有所指向
如果想在给定的结点prev后添加新的值,操作如下:

(1) 使用给定值初始化新结点cur
(2) 将cur的指针指向prev的下一个结点
(3) 将prev的指针指向cur
在开头添加结点:
众所周知,使用头结点来代表整个链表,因此在开头添加结点时需要更新头结点head,操作如下:


(1) 初始化新结点cur
(2) 将新结点cur的指针指向头结点
(3) 将cur指定为head
在链表末尾添加结点,需要从head开始遍历,直到找到最后一个结点,将该节点的指针指向目标节点。
- 删除操作
链表的删除操作由两步组成


(1) 找到待删除结点 cur 的前一个结点 prev 和后一个结点 next
(2) 将 prev 指向 next
同上,删除链表的第一个结点或最后一个结点,只需将第二个结点设为 head 或将倒数第二个结点指向None
四、python实现链表
代码如下
class Node(object):
def __init__(self, val):
self.val = val
self.next = None
class MyLinkedList(object):
def __init__(self):
self.head = None
self.size = 0
def get(self, index):
'''
:param index:
:return:the value of the index-th node
'''
# if index is not int:
# print('please input int')
# return -1
if index >= self.size or index < 0: # 包括链表为空、索引无效
return -1
cur = self.head
for i in range(index):
cur = cur.next
return cur.val
def addAtHead(self, val):
new = Node(val)
new.next = self.head
self.head = new
self.size += 1
def addAtTail(self, val):
new = Node(val)
if self.head is None:
self.head = new
self.size += 1
else:
cur = self.head
while cur.next is not None:
cur = cur.next
cur.next = new
self.size += 1
def addAtIndex(self, index,val): # 在索引前加结点
if index > self.size:
return -1
else:
if index <= 0:
self.addAtHead(val)
elif index == self.size:
self.addAtTail(val)
else:
cur = self.head
pre = self.head
new = Node(val)
for i in range(index):
pre = cur
cur = cur.next
new.next = cur
pre.next = new
self.size += 1
def deleteAtIndex(self,index):
if index < 0 or index >= self.size or self.head is None:
return -1
else:
if index == 0:
self.head = self.head.next
self.size -= 1
return
cur = self.head
pre = self.head
for i in range(index):
pre = cur
cur = cur.next
if cur is None:
pre.next = None
else:
pre.next = cur.next
self.size -= 1

浙公网安备 33010602011771号