python数据结构之链表(linked list)
2018-01-06 15:12
453 查看
目录
基础 知识
1.1 链表的基本结构
1.2 节点类和链表节点的定义
1.3 顺序打印和逆序打印
链表的基本操作
2.1 计算链表长度
2.2 从前,后插入数据
2.3 查找与删除
参考
链表是通过一个个节点组成的,每个节点都包含了称为cargo的基本单元,它也是一种递归的数据结构。它能保持数据之间的逻辑顺序,但存储空间不必按照顺序存储。
如图:
链表的基本元素有:
节点:每个节点有两个部分,左边部分称为值域,用来存放用户数据;右边部分称为指针域,用来存放指向下一个元素的指针。
head:head节点永远指向第一个节点
tail: tail永远指向最后一个节点
None:链表中最后一个节点的指针域为None值
但链表也分为单向链表和单向循环链表,双向链表和双向循环链表,如图为单向链表和单向循环链表:
写个基本程序测试一下:
1.2 节点类和链表节点的定义
节点类定义如下:
因为任何值都能通过str函数,且能存储下来。
链表怎么定义呢?
我们可以先定义一个一个节点,如下:
然后再把每个节点的关系表示出来,就OK了
1.3 顺序打印和逆序打印
因为先前已经建立了关系,所以可以通过输入第一个节点,循环整个链表然后顺序打印整个链表。
使用递归的方法来打印,主要步骤如下:
将list拆分成两个部分,head:第一个元素,tail:其余元素
向后打印
打印第一个元素
事实上,还能更简便。
2.1 计算链表长度
2.2 从前,后插入
从前插入:
被插入数据为空,返回
使用该输入数据创建一个节点,并将该节点指向原来头节点
设置该节点为头节点
时间复杂度和空间复杂度均为O(1)
从后:append
若输入数据为空,返回None
若头节点为空,直接将输入数据作为头节点
遍历整个链表,直到当前节点的下一个节点为None时,将当前节点的下一个节点设置为输入数据
时间复杂度为O(n),空间O(1)
2.3 查找与删除
查找
若查找的数据为空,返回
设置头节点为当前节点,若当前节点不为None,遍历整个链表
若当前节点的data与输入的data相同,但会当前节点,否则轮到下一个节点
可见时间复杂度为O(n),空间复杂度为O(1).
删除1
申请两个变量,如果遇到匹配的,不用删除,直接将匹配节点的前一节点指向匹配节点的下一节点,因此需要定义一个前节点和一个当前节点,当前节点用来判断是否与输入数据匹配,前节点用来更改链表的指向。
若输入数据为None,返回
将头节点设置为前节点,头节点的下一个节点设置为当前节点
判断前节点是否与输入数据匹配,若匹配,将头节点设置为当前节点
遍历整个链表,若当前节点与输入数据匹配,将前节点的指针指向当前节点的下一个节点,否则,移到下一个节点
时间复杂度为O(n),空间复杂度为O(1).
删除2
第二种解决办法就是只定义一个变量作为当前节点,使用它的下一个节点去判断是否与数据数据匹配,若匹配,直接将当前节点指向下下一个节点。
时间复杂度为O(n),空间复杂度为O(1).
reference
Linked lists¶
用Python实现的数据结构与算法:链表
python数据结构-链表
Solution Notebook
基础 知识
1.1 链表的基本结构
1.2 节点类和链表节点的定义
1.3 顺序打印和逆序打印
链表的基本操作
2.1 计算链表长度
2.2 从前,后插入数据
2.3 查找与删除
参考
1.基础 知识
1.1 链表的基本结构链表是通过一个个节点组成的,每个节点都包含了称为cargo的基本单元,它也是一种递归的数据结构。它能保持数据之间的逻辑顺序,但存储空间不必按照顺序存储。
如图:
链表的基本元素有:
节点:每个节点有两个部分,左边部分称为值域,用来存放用户数据;右边部分称为指针域,用来存放指向下一个元素的指针。
head:head节点永远指向第一个节点
tail: tail永远指向最后一个节点
None:链表中最后一个节点的指针域为None值
但链表也分为单向链表和单向循环链表,双向链表和双向循环链表,如图为单向链表和单向循环链表:
写个基本程序测试一下:
1.2 节点类和链表节点的定义
节点类定义如下:
class Node: def __init__(self,cargo = None, next = None): self.cargo = cargo self.next = next def __str__(self): #测试基本功能,输出字符串 return str(self.cargo) print Node("text") #输出text
因为任何值都能通过str函数,且能存储下来。
链表怎么定义呢?
我们可以先定义一个一个节点,如下:
node1 = Node(1) node2 = Node(2) node3 = Node(3)
然后再把每个节点的关系表示出来,就OK了
node1.next = node2 node2.next = node3
1.3 顺序打印和逆序打印
因为先前已经建立了关系,所以可以通过输入第一个节点,循环整个链表然后顺序打印整个链表。
def printList(node): while node: print node node = node.next printList(node1) 1 2 3
使用递归的方法来打印,主要步骤如下:
将list拆分成两个部分,head:第一个元素,tail:其余元素
向后打印
打印第一个元素
def printBackward(lists): if lists == None: return head = lists tail= lists.next print head,tail printBackward(tail) print head,tail printBackward(node1) 1 2 2 3 3 None 3 None 2 3 1 2
事实上,还能更简便。
def printBackward(lists): if lists == None:return printBackward(lists.next) print lists printBackward(node1)
2.链表的基本操作
在链表的基本操作中,包括插入,删除等,但要注意的是一下的操作是针对非循环链表的,从头节点开始操作,而且我们不能插入 None值到链表中。2.1 计算链表长度
class Node(object): #节点类 #功能:输入一个值data,将值变为一个节点 def __init__(self, data, next = None): self.data = data self.next = next def __str__(self): return self.data 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
2.2 从前,后插入
从前插入:
被插入数据为空,返回
使用该输入数据创建一个节点,并将该节点指向原来头节点
设置该节点为头节点
时间复杂度和空间复杂度均为O(1)
def insertToFront(self,data): #功能:输入data,插入到头节点前,并更改为头节点 #输出:当前头节点 if data is None: return None node = Node(data,self.head) self.head = node return node
从后:append
若输入数据为空,返回None
若头节点为空,直接将输入数据作为头节点
遍历整个链表,直到当前节点的下一个节点为None时,将当前节点的下一个节点设置为输入数据
时间复杂度为O(n),空间O(1)
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
2.3 查找与删除
查找
若查找的数据为空,返回
设置头节点为当前节点,若当前节点不为None,遍历整个链表
若当前节点的data与输入的data相同,但会当前节点,否则轮到下一个节点
可见时间复杂度为O(n),空间复杂度为O(1).
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
删除1
申请两个变量,如果遇到匹配的,不用删除,直接将匹配节点的前一节点指向匹配节点的下一节点,因此需要定义一个前节点和一个当前节点,当前节点用来判断是否与输入数据匹配,前节点用来更改链表的指向。
若输入数据为None,返回
将头节点设置为前节点,头节点的下一个节点设置为当前节点
判断前节点是否与输入数据匹配,若匹配,将头节点设置为当前节点
遍历整个链表,若当前节点与输入数据匹配,将前节点的指针指向当前节点的下一个节点,否则,移到下一个节点
时间复杂度为O(n),空间复杂度为O(1).
def delete(slef,data): #删除节点 if data is None: return None if self.head is None: return None if self.head.data == data: self.head = self.head.next return prev_node = self.head curr_node = self.head.next while curr_node is not None: if curr_node.data == data: prev_node.next = curr_node.next else: prev_node = curr_node curr_node = curr_node.next
删除2
第二种解决办法就是只定义一个变量作为当前节点,使用它的下一个节点去判断是否与数据数据匹配,若匹配,直接将当前节点指向下下一个节点。
时间复杂度为O(n),空间复杂度为O(1).
def deleteAlt(self): #只定义一个变量来完成删除操作 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
reference
Linked lists¶
用Python实现的数据结构与算法:链表
python数据结构-链表
Solution Notebook
相关文章推荐
- [笔记]python数据结构之线性表:linkedlist链表,stack栈,queue队列
- 【数据结构】链表LinkedList分析与关键实现
- (8) Java源码分析 ---- LinkedList (对应数据结构中线性表中的双向循环链表,JDK1.6)
- LeetCode--Reverse Linked List 反转链表(Python)
- php数据结构之双向链表(SplDoublyLinkedList)
- 《数据结构》2.3单链表(single linked list)
- Linked List Cycle(判断链表是否有环)-python
- python数据结构:bitmap,list链表,树,图
- 数据结构和算法 python(1)链表 list
- 【数据结构】Singly-Linked-List 单链表(更新时间:2016-04-07)
- Java数据结构-线性表之单链表LinkedList
- 数据结构:链表(linked-list)
- Python 数据结构与算法——列表(链表,linked list)
- Python数据结构与算法之列表(链表,linked list)简单实现
- Android版数据结构与算法(三):基于链表的实现LinkedList源码彻底分析
- Java数据结构-线性表之单链表LinkedList
- LeetCode--Delete Node in a Linked List(删除链表中的节点)Python
- [java数据结构]--java双向链表LinkedList的简单实现
- java数据结构——LinkedList(单链表)
- 用LinkedList链表模拟 堆栈、队列 两种数据结构