1. 链表的概念
1.1 单链表
什么是链表?把链表比作项链,元素之间通过结点相互连接,为了找到下一个部分,每个结点会有一个指向下一个元素的next指针,由于是单向搞得链表,最后一个元素就找不到下一个部分,所以单链表最后一个元素的next指向null。
1.2 链表的相关概念
节点:在链表中,每个点都由值指向下一个结点的地址组成的独立的单元,叫做节点或者结点
头节点:对于单链表,知道了第一个元素,就可以通过遍历访问整个链表,第一个节点是头节点
虚拟节点:next指针指向head, dummyNode.next=head。其实这块概念不太懂,指的是一个虚拟出来的指向头节点的节点吗?
2. 链表的创建
定义一个课程的类:
class Course:
teacher = None
student = None
这里的teacher和student就是指向堆的引用。没学过数据结构的哭了,不懂堆和栈的概念
class Course:
def __init__(self,val):
self.val = val
self.next = None
next指向洗一个同为course类型的对象,通过栈的引用(地址),是指有一个可识别的地址吗?可以找到val(1),然后val(1)节点又指向val(2)的地址,而val(3)又指向了val(4)的地址,构造出链式访问结构
__init__方法用于初始化对象,getData和setData方法用于获取和设置data属性,get_next和set_next方法用于获取和设置next属性,但说实话没太懂下面这段代码的意思~~
class ListNode:
def __init__(self,data):
self.data = data
self.next = None
def get_data(self):
return self.data
def set_data(self,data):
self.data = data
def get_next(self):
return self.next
def set_next(self,next):
self.next = next
LeetCode算法题中这样创建链表:
class ListNode:
def __init__(self,val=0,next = None):
self.val = val
self.next = next
listnode = ListNode(1)
3.链表的增删改查
3.1 遍历链表
对于单链表的而言,不管什么操作,都是从头逐个向后访问
def length(self):
'''链表长度'''
# cur初始时指向头节点
cur = self._head
count = 0
# 尾节点指向None,当未达到尾部时
while cur != None:
count += 1
# 将cur后移一个节点
cur = cur.next
return count
3.2 链表插入
-
表头插入:把新插入的节点地址指向表头,newNode.next = head
-
中间插入:在中间要把原来指向下一个节点的地址指向新节点,然后把新节点的地址指向下一个节点
-
结尾插入节点:将尾节点指向新节点,再将新节点指向null
-
当head = null时,插入的节点就是链表的头结点,可以直接抛出不能插入的异常
def insert(self,pos, item):
'''指定位置增加元素'''
# 若指定位置pos为第一个元素之前,则执行头部插入
if pos <= 0:
self.add(item)
#若指定位置超过链表尾部,则执行尾部插入
elif pos > (self.length()-1):
self.append(item)
count = 0
# 指定指定位置
else:
node = Node(item)
count = 0
# pre用来指向指定位置pos的前一个位置pos-1,初始头节点开始移动到指定位置
pre = self._head
while count < (pos - 1):
count += 1
pre = pre.next
# 将新节点node的next指定位置的节点
node.next = pre.next
# 将插入位置的前一个节点的next指向新节点
pre.next = node
3.3 链表的删除
链表删除和插入一样,同样分为删除头部元素,中间元素和尾部元素,要删除某个元素,要先遍历链表,找到目标元素,然后再删除
- 删除表头节点:只要让head = head.next
- 删除中间节点:将cur.next指针的值更新为cur.next.next
- 删除最后一个节点:先判断cur.next是否为要删除的元素,如果是,则直接执行让cur.next = null
# 删除节点
def remove(self, item):
'''删除节点'''
cur = self._head
pre = None
while cur != None:
# 找到指定元素
if cur.item == item:
# 如果第一个是删除的节点
if not pre:
# 将头指针指向头节点的后一个节点
self._head = cur.next
else:
# 将删除位置前一个的next指向删除位置的后一个节点
pre.next = cur.next
break
else:
# 继续按链表后移节点
pre = cur
cur = cur.next