线性表学习笔记
线性表
队列
本质是排队 先进先出
python里面的列表就是一个队列
下面构造一个环形队列
class Queue:
def __init__(self,size=100):
self.queue=[0 for _ in range(size)]
#元素只能储存size-1个
self.size=size
#通过构建头指针和尾指针来进行元素的插入和删除
self.rear=0
self.front=0
def push(self,element):
#尾部指针进行移动
if not self.is_filled():
self.rear=(self.rear+1)%self.size
self.queue[self.rear]=element
else:
raise IndexError('queue is filled')
def pop(self):
if not self.is_empty():
self.front=(self.front+1)%self.size
return self.queue[self.front]
else:
raise IndexError('Queue is empty')
def is_empty(self):
return self.front==self.rear
def is_filled(self):
return (self.rear+1)%self.size == self.front
q=Queue(3) #只能储存2个元素
q.push(1)
q.push(2)
q.is_filled()
q.pop()
链表
首先 先建立一个结点对象
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class LinkList:
def __init__(self):
self.head=None
##检验是不是空的
def isEmpty(self):
return self.head==None
#将列表创建成一个新的链表
def initList(self, data):
# 创建头结点
self.head = ListNode(data[0])
p = self.head #指针
# 逐个为 data 内的数据创建结点, 建立链表
for i in data[1:]:
node = ListNode(i)
p.next = node
p = p.next
return self.head
# 打印链表
def printlist(self,head,name=' '):
#设置这个name参数主要是想在打印的是时候更加明了的知道在打印哪个变量
#并没有改变 head
if head == None:
print(name,'空元素')
return
node = head
print(name+' ',end='')
while node != None:
print(node.val,end='')
node = node.next
print('\n')
def printlist1(self,head):
#直接输出链表的每个值
if head == None:
return
node = head
while node != None:
print(node.val,end='')
node = node.next
#思考一下 这里的head是啥 会不会有所改变 不会改变的啦
# 输出链表长度
def __len__(self):
count=0
p=self.head #指针
while p != None:
count += 1
p=p.next
return count
#输出元素列表
def __str__(self):
value_list=[]
p=self.head
while p != None:
value_list.append(p.val)
#print(p.val,end=' ')
p=p.next
#必须要传出去str类型****
return str(value_list)
#尾部添加元素
def pushBack(self,value):
node=ListNode(value)
if self.isEmpty():
self.head=node
else:
p=self.head
while p.next != None:
p=p.next
p.next=node
# 尾部删除一个元素
def popBack(self):
pop_node=None
#分类讨论 无节点 单个节点 多个节点
if self.head==None:
pass
elif self.head.next==None:
pop_node=self.head
self.head=None
else:
p=self.head
pop_node=self.head.next
while p.next!=None:
p=p.next
pop_node=p.next
p.next=None
if pop_node!=None:
return pop_node.val
return None
#从头部插入节点
def pushFront(self,value):
new_node=ListNode(value)
new_node.next=self.head
self.head=new_node
#从头部删除
def popFront(self):
pop_node=self.head
if self.head!=None:
self.head=self.head.next
if pop_node!=None:
return pop_node.val
return None
def reverse(self,head):
#反转链表
if head:
prev=None
while head:
tmp=head.next
head.next=prev
prev=head
head=tmp
return self.printlist1(prev)
else:
return None
if __name__ == '__main__':
L1=LinkList()
data1 = [1, 2, 3]
l1=L1.initList(data1)
print(str(L1))
print(len(L1))
print(L1==l1)
#print(len(l1)) #l1 这样就不行 此时l1并不具备L1的属性
print(type(L1))
print(type(l1))
前面都是创建链表对象,进行基本的增删改查
现在通过刷题 来对链表有更加深刻的理解
exerise 前情准备
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
def initList(data):
# 创建头结点
if data:
head = ListNode(data[0])
p = head
# 逐个为 data 内的数据创建结点, 建立链表
for i in data[1:]:
node = ListNode(i)
p.next = node
p = p.next
return head
def printlist(head,name='变量'):
if head == None:
print(name,'空元素')
return
node = head
print(name+': ',end='')
while node != None:
print(node.val,end='')
node = node.next
print('\n')
exerise1 链表反转
def reverse(head):
if head:
prev=None
while head:
tmp=head.next
head.next=prev
prev=head
head=tmp
return prev
else:
return None
exerise2 链表内指定区间进行反转
方法一 头插迭代法
- 1.先在链表插入一个表头 后续返回时去掉
- 2.使用双指针,一个指向当前节点,一个指向前序节点
- 3.依次遍历链表,到第m个位置
- 4.对于从m到n这些个位置的节点,依次断掉只想后续的指针
def reverseBetween(head: ListNode, m: int, n: int) -> ListNode:
#前序结点
res = ListNode(-1)
res.next=head
#当前结点
pre=res
cur=head
# 找到m
for i in range(1,m):
pre=cur
cur=cur.next
for i in range(m,n):
tmp=cur.next
cur.next=tmp.next
tmp.next=pre.next
pre.next=tmp
self.printlist(res.next,name='res.next')
self.printlist(head,name='head')
self.printlist(pre,name='pre')
print('********')