【算法】链表
链表基础(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())