链表
链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)
链表的入口节点称为链表的头结点也就是head
类型:
单链表/双链表/循环链表
双链表
单链表中的指针域只能指向节点的下一个节点。
双链表:每一个节点有两个指针域,一个指向下一个节点,一个指向上一个节点。
双链表 既可以向前查询也可以向后查询。
链表存储方式:
数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。链表是通过指针域的指针链接在内存中各个节点
链表的python实现
class Node():
def __init__(self,item):
self.item=item #数据域
self.next=Node #指针域
a=Node(1)
b=Node(2)
c=Node(3)
a.next=b
b.next=c
# print(a.next.next.item) #3
#遍历列表
def print_linklist(lk): #lk是head
while lk.next!=None:
print(lk.item, end=',')
lk = lk.next
#python创建链表
#头插法
def create_linklist_head(li):
head=Node(li[0])
for element in li[1:]:
node=Node(element)
node.next=head
head=node
return head
# lk=create_linklist_head([1,2,3])
# print_linklist(lk)
#尾插法
def create_linklist_tail(li):
head=Node(li[0])
tail=head
for element in li[1:]:
node=Node(element)
tail.next=node
tail=node
return head
lk2=create_linklist_tail([1,2,4,6,7,8])
print_linklist(lk2)
python设计链表
在链表类中实现这些功能:
get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
代码
class ListNode:
def __init__(self,val):
self.val=val
self.next=None
class MyLinkedList:
def __init__(self):
self.size=0 # 设置一个链表长度的属性,便于后续操作,注意每次增和删的时候都要更新
self.head=ListNode(0) #这里相当于添加了一个虚拟头结点
def get(self, index: int) -> int:
if index<0 or index >=self.size:
return -1
cur=self.head #当前指针指向虚拟头结点
for _ in range(index+1): #index+1也是因为虚拟头结点多出来的1,例如查看链表第index=0节点的值,这里遍历0+1=1次
cur=cur.next #指针指向链表第index=0节点
return cur.val
def addAtHead(self, val: int) -> None:
new_Node=ListNode(val) #创建新节点
new_Node.next=self.head.next #新节点的next指向原链表的第一个节点,self.head表示虚拟头结点,虚拟头结点的下一个节点就是实际链表的头节点
self.head.next=new_Node #新节点接在虚拟头结点的后面
self.size+=1
def addAtTail(self, val: int) -> None:
new_Node=ListNode(val) #创建新节点
cur=self.head #指针指向头结点
while cur.next!=None: #只要下一个节点存在,
cur=cur.next #就让指针指向下一个节点,直到当前链表的最后一个节点
cur.next=new_Node #然后让这最后一个节点的next指向新节点
new_Node.next=None
self.size+=1
def addAtIndex(self, index: int, val: int) -> None:
if index<0:
self.addAtHead(val)
return
if index==self.size:
self.addAtTail(val)
return
if index>self.size:
return
new_node=ListNode(val)
cur=self.head
for _ in range(index): #,例如在链表第index=1节点处插入,这里遍历1次
cur=cur.next #遍历第一次,指针指向链表第index=0节点
new_node.next=cur.next #新节点(index=1)后面接原链表index=1的节点
cur.next=new_node #新节点接在原链表index=0节点的后面
self.size+=1
def deleteAtIndex(self, index: int) -> None:
if index<0 or index>=self.size:
return
cur=self.head
for _ in range(index):
cur=cur.next
cur.next=cur.next.next
self.size-=1
lk=MyLinkedList()
lk.addAtHead(1)
lk.addAtHead(2)
lk.addAtHead(3)
lk.addAtTail(0)
lk.addAtIndex(2,10)
lk.deleteAtIndex(2)
for i in range(lk.size):
print(lk.get(i))