链表基础(Linked list)
定义
链表:是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)
链表的基本元素:
- 节点:每个节点有两个部分,左边部分称为值域,用来存放用户数据;右边部分称为指针域,用来存放指向下一个元素的指针。
- head:head节点永远指向第一个节点
- tail: tail永远指向最后一个节点
- None:链表中最后一个节点的指针域为None值
时间复杂度
由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。
节点&链表定义
节点定义
#encoding=utf-8
class Node:
def __init__(self,value = None, next = None):
self.value = value
self.next = next
def __str__(self):
#测试基本功能,输出字符串
return str(self.value)
print (Node("text"))
链表定义
逐个定义节点,再把每个节点的关系表示出来。
#encoding=utf-8
class Node:
def __init__(self,value = None, next = None):
self.value = value
self.next = next
def __str__(self):
return str(self.value)
#定义每个节点
node1=Node(1)
node2=Node(2)
node3=Node(3)
#定义关系
node1.next=node2
node2.next=node3
顺序打印和逆序打印
顺序打印
通过输入第一个节点,循环整个链表,顺序打印整个链表
#encoding=utf-8
class Node:
def __init__(self,value = None, next = None):
self.value = value
self.next = next
def __str__(self):
return str(self.value)
#定义每个节点
node1=Node(1)
node2=Node(2)
node3=Node(3)
#定义关系
node1.next=node2
node2.next=node3
def printlist(node):
while node:
print(node)
node=node.next
printlist(node1)
运行结果
1
2
3
逆序打印
使用递归的方法打印全部链表元素,顺序为逆序
#encoding=utf-8
class Node:
def __init__(self,value = None, next = None):
self.value = value
self.next = next
def __str__(self):
return str(self.value)
#定义每个节点
node1=Node(1)
node2=Node(2)
node3=Node(3)
#定义关系
node1.next=node2
node2.next=node3
def printBackward(node):
if node == None:
return
head = node
tail= node.next
printBackward(tail)
print (head,tail)
printBackward(node1)
运行结果
3 None
2 3
1 2
计算链表的长度
#encoding=utf-8
class Node(object):#节点类
#功能:输入一个值data,将值变为一个节点
def __init__(self, data, next = None):
self.data = data
self.next = next
def __str__(self):
return self.data
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node1.next = node2
node2.next = node3
class LinkedList(object):
def __init__(self, head = None):
self.head = head
def __len__(self):
#功能:输入头节点,返回链表长度
curr = self.head
counter = 0
while curr is not None:
counter += 1
curr = curr.next
return counter
print(len(LinkedList(node1)))
运行结果
3
在链表中插入数据
从链表的前面插入数据
步骤:
- 被插入数据为空,返回
- 使用该输入数据创建一个节点,并将该节点的next指向原来头节点
- 设置该节点为头节点
代码实现:
#encoding=utf-8
class Node(object):
#节点类
#功能:输入一个值data,将值变为一个节点
def __init__(self, data, next = None):
self.data = data
self.next = next
def __str__(self):
return self.data
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node1.next = node2
node2.next = node3
class LinkedList(object):
def __init__(self, head = None):
self.head = head
def __len__(self):
#功能:输入头节点,返回链表长度
curr = self.head
counter = 0
while curr is not None:
counter += 1
curr = curr.next
return counter
def insertToFront(self, data):
# 功能:输入data,插入到头节点前,并更改为头节点
# 输出:当前头节点
if data is None:
return None
node = Node(data, self.head)
self.head = node
return node
node4 = Node(4)
link_list = LinkedList(node1)#创建一个链表实例,链表从node1开始
link_list.insertToFront(node4)
print(len(link_list))
运行结果
4
从链表的后面插入数据
步骤
- 若输入数据为空,返回None
- 若头节点为空,直接将输入数据作为头节点
- 若非空,则遍历整个链表,直到当前节点的下一个节点为None时,将当前节点的下一个节点设置为输入数据
代码实现:
#encoding=utf-8
class Node(object):
#节点类
#功能:输入一个值data,将值变为一个节点
def __init__(self, data, next = None):
self.data = data
self.next = next
def __str__(self):
return self.data
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node1.next = node2
node2.next = node3
class LinkedList(object):
def __init__(self, head = None):
self.head = head
def __len__(self):
#功能:输入头节点,返回链表长度
curr = self.head
counter = 0
while curr is not None:
counter += 1
curr = curr.next
return counter
def insertToFront(self, data):
# 功能:输入data,插入到头节点前,并更改为头节点
# 输出:当前头节点
if data is None:
return None
node = Node(data, self.head)
self.head = node
return node
def append(self, data):
# 功能:输入data,作为节点插入到末尾
if data is None:
return None
node = Node(data)
if self.head is None:
self.head = node
return node
curr_node = self.head
while curr_node.next is not None:
curr_node = curr_node.next
curr_node.next = node
return node
node4 = Node(4)
link_list = LinkedList(node1)
link_list.append(node4)
print(len(link_list))
在链表的中间插入数据
#encoding=utf-8
class Node(object):
#节点类
#功能:输入一个值data,将值变为一个节点
def __init__(self, data, next = None):
self.data = data
self.next = next
def __str__(self):
return str(self.data)
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node1.next = node2
node2.next = node3
class LinkedList(object):
def __init__(self, head = None):
self.head = head
def __len__(self):
#功能:输入头节点,返回链表长度
curr = self.head
counter = 0
while curr is not None:
counter += 1
curr = curr.next
return counter
def insertToFront(self, data):
# 功能:输入data,插入到头节点前,并更改为头节点
# 输出:当前头节点
if data is None:
return None
node = Node(data, self.head)
self.head = node
return node
def append(self, data):
# 功能:输入data,作为节点插入到末尾
if data is None:
return None
node = Node(data)
if self.head is None:
self.head = node
return node
curr_node = self.head
while curr_node.next is not None:
curr_node = curr_node.next
curr_node.next = node
return node
def insertAmong(self,data,site):
#功能:输入data,插到指定site前。
#输出:插入的data
if data is None:
return None
if self.head is None:
return None
if site is None:
return None
node = Node(data)
curr_node = self.head
while curr_node.next is not None:
if curr_node.next.data==site:
tmp=curr_node.next
curr_node.next=node
node.next=tmp
return node
else:
curr_node=curr_node.next
return 'insert fail'
link_list = LinkedList(node1)
print(link_list.insertAmong(5,2))
print(len(link_list )
在链表中查找元素
#encoding=utf-8
class Node(object):
#节点类
#功能:输入一个值data,将值变为一个节点
def __init__(self, data, next = None):
self.data = data
self.next = next
def __str__(self):
return str(self.data)
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node1.next = node2
node2.next = node3
class LinkedList(object):
def __init__(self, head = None):
self.head = head
def __len__(self):
#功能:输入头节点,返回链表长度
curr = self.head
counter = 0
while curr is not None:
counter += 1
curr = curr.next
return counter
def insertToFront(self, data):
# 功能:输入data,插入到头节点前,并更改为头节点
# 输出:当前头节点
if data is None:
return None
node = Node(data, self.head)
self.head = node
return node
def append(self, data):
# 功能:输入data,作为节点插入到末尾
if data is None:
return None
node = Node(data)
if self.head is None:
self.head = node
return node
curr_node = self.head
while curr_node.next is not None:
curr_node = curr_node.next
curr_node.next = node
return node
def find(self, data):
# 功能:查找链表的节点data与data相同的节点
if data is None:
return None
curr_node = self.head
while curr_node is not None:
if curr_node.data == data:
return curr_node
curr_node = curr_node.next
return None
link_list = LinkedList(node1)
print(link_list.find(2))
删除元素
只定义一个变量作为当前节点,使用它的下一个节点去判断是否与数据数据匹配,若匹配,直接将当前节点指向下下一个节点。
#encoding=utf-8
class Node(object):
#节点类
#功能:输入一个值data,将值变为一个节点
def __init__(self, data, next = None):
self.data = data
self.next = next
def __str__(self):
return str(self.data)
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node1.next = node2
node2.next = node3
class LinkedList(object):
def __init__(self, head = None):
self.head = head
def __len__(self):
#功能:输入头节点,返回链表长度
curr = self.head
counter = 0
while curr is not None:
counter += 1
curr = curr.next
return counter
def insertToFront(self, data):
# 功能:输入data,插入到头节点前,并更改为头节点
# 输出:当前头节点
if data is None:
return None
node = Node(data, self.head)
self.head = node
return node
def append(self, data):
# 功能:输入data,作为节点插入到末尾
if data is None:
return None
node = Node(data)
if self.head is None:
self.head = node
return node
curr_node = self.head
while curr_node.next is not None:
curr_node = curr_node.next
curr_node.next = node
return node
def find(self, data):
# 功能:查找链表的节点data与data相同的节点
if data is None:
return None
curr_node = self.head
while curr_node is not None:
if curr_node.data == data:
return curr_node
curr_node = curr_node.next
return None
def deleteData(self,data):
# 只定义一个变量来完成删除操作
if data is None:
return
if self.head is None:
return
if self.head.data == data:
self.head = self.head.next
return
curr_node = self.head
while curr_node.next is not None:
if curr_node.next.data == data:
curr_node.next = curr_node.next.next
return
curr_node = curr_node.next
link_list = LinkedList(node1)
print(link_list.deleteData(2))
print(len(link_list ))
PS:包含全部功能的代码
#encoding=utf-8
class Node(object):
#节点类
#功能:输入一个值data,将值变为一个节点
def __init__(self, data, next = None):
self.data = data
self.next = next
def __str__(self):
return str(self.data)
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node1.next = node2
node2.next = node3
class LinkedList(object):
def __init__(self, head = None):
self.head = head
def __len__(self):
#功能:输入头节点,返回链表长度
curr = self.head
counter = 0
while curr is not None:
counter += 1
curr = curr.next
return counter
def insertToFront(self, data):
# 功能:输入data,插入到头节点前,并更改为头节点
# 输出:当前头节点
if data is None:
return None
node = Node(data, self.head)
self.head = node
return node
def append(self, data):
# 功能:输入data,作为节点插入到末尾
if data is None:
return None
node = Node(data)
if self.head is None:
self.head = node
return node
curr_node = self.head
while curr_node.next is not None:
curr_node = curr_node.next
curr_node.next = node
return node
def insertAmong(self,data,site):
#功能:输入data,插到指定site前。
#输出:插入的data
if data is None:
return None
if self.head is None:
return None
if site is None:
return None
node = Node(data)
curr_node = self.head
while curr_node.next is not None:
if curr_node.next.data==site:
tmp=curr_node.next
curr_node.next=node
node.next=tmp
return node
else:
curr_node=curr_node.next
return 'insert fail'
def printList(self):
#功能:顺序打印链表。将链表顺序储存在一个list中。
l=[]
curr = self.head
while curr:
l.append(curr.data)
curr=curr.next
return l
def find(self, data):
# 功能:查找链表的节点data与data相同的节点
if data is None:
return None
curr_node = self.head
while curr_node is not None:
if curr_node.data == data:
return curr_node
curr_node = curr_node.next
return None
def deleteData(self,data):
# 只定义一个变量来完成删除操作
if data is None:
return
if self.head is None:
return
if self.head.data == data:
self.head = self.head.next
return
curr_node = self.head
while curr_node.next is not None:
if curr_node.next.data == data:
curr_node.next = curr_node.next.next
return
curr_node = curr_node.next
link_list = LinkedList(node1)
print(link_list.insertAmong(5,2))
print(len(link_list ))
print(link_list.printList())