文末附有本节课单链表操作全部代码

一、课程目标
  • 链表数据的结构
  • 链表结构的python实现
  • 链表的操作时间复杂度
二、详情解读

01.链表结构:

链表就好像链条一样,一节就是一个数据节点。

python有链表吗 python链表详解_单链表操作的Python实现


python有链表吗 python链表详解_python有链表吗_02


python有链表吗 python链表详解_python有链表吗_03


python有链表吗 python链表详解_插入节点_04


链表特点:

  • 1、每一个数据节点包括数据本身以及前后节点位置(单链表只包含下一节点位置)
  • 2、链表不需要连续内存空间
  • 3、插入快,查询慢

02、链表的python实现

单链表节点类

class Node:
	def __init__(self, data, next=None):
		self.data = data
		self.next = next

python有链表吗 python链表详解_python有链表吗_05


节点创建

node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node1.next = node2
node2.next = node3

print(node2.data)  # 2
print(node1.next.data) # 2
print(node1.next.next.data) # 3
print(node2.data)  # 3

python有链表吗 python链表详解_插入节点_06


单链链表数据结构

class Node:
    def __init__(self, data, next=None):
        self.data = data
        self.next = next

    def get_data(self):
        return self.data

    def get_next(self):
        return self.next

    def set_data(self, new_data):
        self.data = new_data


class LinkedList:
    def __init__(self):
        self.head = None
        self.length = 0

    def __len__(self):
        return self.length

    def insert_head(self, node):
        '''
        插入节点
        '''
        self.head, node.next = node, self.head
        self.length += 1

    def __iter__(self):
        '''
        遍历链表
        '''
        head = self.head
        while head is not None:
            current, head = head, head.next
            yield current

# 创建一个列表
linkedlist= LinkedList()
for i in range(10):
    node = Node(i)
    linkedlist.insert_head(node)
print(len(linkedlist)) # 10
print([node.data for node in linkedlist]) # [9,8,7,6,5,4,3,2,1,0]

单链表遍历

python有链表吗 python链表详解_python_07

current = linkedlist.head
while current is not None:
	current = current.next

从末尾插入数据

python有链表吗 python链表详解_插入节点_08

new_node = Node('new node')
current = linkedlist.head
while current is not None:
	current = current.next
current.next = new_node
def append_node(self, node):
    '''
    末尾插入节点
    '''
    current = self.head
    while current.next is not None:
        current = current.next
    current.next = node
    self.length += 1

new_node = Node('new Node')
linkedList.append_node(new_node)
print([node.data for node in linkedList]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 'new Node']

从开始处删除节点:

python有链表吗 python链表详解_python有链表吗_09

linkedlist.head = linkedlist.head.next
# 弹出并返回第一个节点
def pop_first(self):
	head = self.head
	if self.head is not None:
		self.head = self.head.next
	self.length -= 1
	return head

d = linkedlist.pop_first()
print(d.data) # 9
print([node.data for node in linkedList]) # [8, 7, 6, 5, 4, 3, 2, 1, 0, 'new Node']

从末尾处删除:

python有链表吗 python链表详解_插入节点_10

current = linkedlist.head
while current.next.next is not None:
	current = current.next
current.next = None
# 弹出最后一个节点
def pop_last(self):
	current = self.head
	while current.next.next is not None:
		current = current.next
	node, current.next = current.next, None
	self.length -= 1
	return node

d = linkedlist.pop_last()
print(d.data) # new node
print([node.data for node in linkedlist]) # [8,7,6,5,4,3,2,1,0]

从任意处插入数据:

python有链表吗 python链表详解_python_11

new_node = Node("new_index")
if linkedlist.head is None or index < 1:
	linkedlist.head, new_node.next = new_node, linkedlist.head
else:
	current = linkedlist.head
	while index > 1 and current.next is not None:
		current = current.next
		index -= 1
	current.next, new_node.next = new_node, current.next
# 从index处插入节点
def insert(self, index, new_node):
	if self.head is None or index < 1:
		self.head, new_node.next = new_node, self.head
	else:
		current = self.head
		while index > 1 and current.next i not None:
			current = current.next
			index -= 1
		current.next, new_node.next = new_node, current.next
		self.length += 1

# 从第index处插入节点
index = 3
new_node = Node("new_index")
linkedlist.insert(index, new_node)
print(len(linkedlist)) # 10
print([node.data for node in linkedlist]) # [8, 7, 6, 'new_index', 5, 4, 3, 2, 1, 0]

从任意处删除数据:

python有链表吗 python链表详解_插入节点_12

if linkedlist.head.next is None or index < 0:
	linkedlist.head = None
else:
	current = linkedlist.head
	while index > 1 and current.next is not None:
		current = current.next
		index -= 1
	current.next = current.next.next
# 删除index处节点
def remove(self, index):
	if self.head is None or index < 0:
		return None
	else:
		current = self.head
		while index > 1 and current.next is not None:
			current = current.next
			index -= 1
		current.next = current.next.next
		self.legnth -= 1

# 删除index处节点
index = 4
linkedlist.remove(index)
print(len(linkedlist)) # 9
print([node.data for node in linkedlist]) # [8, 7, 6, 'new_index', 4, 3, 2, 1, 0]

03.时间复杂度:

各项操作时间复杂度

操作

复杂度

从第i个位置访问

O(n)

在第i个位置替换

O(n)

从末尾插入数据

O(n)

从末尾删除

O(n)

从第i个位置插入

O(n)

从第i个位置删除

O(n)

从开始处插入

O(1)

从开始处删除

O(1)

课外练习:用Python实现双链表的上述操作(面试常考)

单链表优势:

python有链表吗 python链表详解_插入节点_13

1、内存空间利用率高(不需要连续内存空间),空间复杂度低
2、适合开始处插入,开始处读取的场景

三、课程小结
  • 学习了链表结构
  • 学习了单链表的实现
  • 学习了单链表操作的时间复杂度

本节课单链表操作全部代码:

class Node:
    def __init__(self, data, next=None):
        self.data = data
        self.next = next

    def get_data(self):
        return self.data

    def get_next(self):
        return self.next

    def set_data(self, new_data):
        self.data = new_data


class LinkedList:
    def __init__(self):
        self.head = None
        self.length = 0

    def __len__(self):
        return self.length

    def insert_head(self, node):
        '''
        插入节点
        '''
        self.head, node.next = node, self.head
        self.length += 1

    def __iter__(self):
        '''
        遍历链表
        '''
        head = self.head
        while head is not None:
            current, head = head, head.next
            yield current

    def append_node(self, node):
        '''
        末尾插入节点
        '''
        current = self.head
        while current.next is not None:
            current = current.next
        current.next = node
        self.length += 1

    def pop_first(self):
        '''
        弹出并返回第一个节点
        '''
        head = self.head
        if self.head is not None:
            self.head = self.head.next
        self.length -= 1
        return head

    def pop_last(self):
        '''
        弹出最后一个节点
        '''
        current = self.head
        while current.next.next is not None:
            current = current.next
        node, current.next = current.next, None
        self.length -= 1
        return node

    def insert(self, index, new_node):
        '''
        在第index处插入数据
        '''
        if self.head is None or index < 1:
            self.head, new_node.next = new_node, self.head
        else:
            current = self.head
            while index > 1 and current.next is not None:
                current = current.next
                index -= 1
            current.next, new_node.next = new_node, current.next
            self.length += 1

    def remove(self, index):
        '''
        删除index处节点
        '''
        if self.head is None or index < 0:
            return None
        else:
            current = self.head
            while index > 1 and current.next is not None:
                current = current.next
                index -= 1
            current.next = current.next.next
            self.length -= 1


# 创建一个列表
linkedlist = LinkedList()
for i in range(10):
    node = Node(i)
    linkedlist.insert_head(node)
print(len(linkedlist)) # 10
print([node.data for node in linkedlist]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

# 在末尾处插入节点
new_node = Node('new Node')
linkedlist.append_node(new_node)
print(len(linkedlist)) # 11
print([node.data for node in linkedlist]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 'new Node']

# 弹出并返回第一个节点
d = linkedlist.pop_first()
print(d.data) # 9
print(len(linkedlist)) # 10
print([node.data for node in linkedlist]) # [8, 7, 6, 5, 4, 3, 2, 1, 0, 'new Node']

# 弹出最后一个节点
d = linkedlist.pop_last()
print(d.data) # new Node
print(len(linkedlist)) # 9
print([node.data for node in linkedlist]) # [8, 7, 6, 5, 4, 3, 2, 1, 0]

# 从第index处插入节点
index = 3
new_node = Node("new_index")
linkedlist.insert(index, new_node)
print(len(linkedlist)) # 10
print([node.data for node in linkedlist]) # [8, 7, 6, 'new_index', 5, 4, 3, 2, 1, 0]

# 删除index处节点
index = 4
linkedlist.remove(index)
print(len(linkedlist)) # 9
print([node.data for node in linkedlist]) # [8, 7, 6, 'new_index', 4, 3, 2, 1, 0]