第一章 链表
1.1如何实现链表的逆序
题目描述:给定一个带头结点的单链表,请将其逆序。如果单链表原来为head->1->2->3->4->5->6->7,那么逆序后为head->7->6->5->4->3->2->1
方法一:就地逆序
在遍历链表时,修改当前结点的指针方向,让它指向前驱结点。为此定义一个指针变量来保存前驱结点的地址;除此之外,为了能找到后继结点,还需定义一个指针变量保存后继结点的地址,当所有的结点保存好以后就可以完成逆序了。
pre:表示前驱结点
cur:表示当前结点
next:表示后继结点
##################################
#链表的数据结构#
##################################
class LNode:
def __init__(self,x):
self.data = x #数据域
self.next = None #指针域
#################################
#具体代码实现
#################################
def Reverse(head):
#判断链表是否为空
if head == None or head.next == None:
return
pre = None #前驱结点
cur = None #当前结点
next = None #后继结点
#把链表首结点变为尾结点
cur = head.next #把头结点的下一个结点作为当前结点
next = cur.next #当前结点的下一结点作为后继结点
cur.next = None #将后继结点的指针赋给空值
pre = cur #将结点后移,原来的当前结点作为现在的前驱结点
cur = next #将原来的后继结点作为现在的当前结点
#使当前遍历到的结点cur指向其前驱结点
while cur.next != None: #当遍历到尾结点时就退出循环
next = cur.next #记录当前结点的后继结点
cur.next = pre #当前结点指向前驱结点
pre = cur #并将原来的当前结点作为现在的前驱结点
cur = cur.next #遍历下一结点
cur = next #并将原来的后继结点作为当前结点
#链表最后一个结点指向倒数第二个结点
cur.next = pre
#链表的头结点指向原来链表的尾结点
head.next = cur
if __name__ == "__main__":
i = 1
#链表头结点
head = LNode()
head.next = None
tmp = None
cur = head
#构造单链表
while i<8:
tmp = LNode()
tmp.data = i
tmp.next = None
cur.next = tmp
cur = tmp
i += 1
print("逆序前:")
cur = head.nex
t
while cur != None:
print(cur.data)
cur = cur.next
print("\n 逆序后:")
Reverse(head)
cur = head.next
while cur != None:
print(cur.data)
cur = cur.next
时间复杂度:O(N)
空间复杂度:O(1)
方法二:递归法
先逆序除第一个结点以外的子链表(将1->2->3->4->5->6->7变为1->7->6->5->4->3->2),接着将结点1添加到逆序的子链表后面(1->7->6->5->4->3->2变为7->6->5->4->3->2->1)
####################################
#具体代码实现
####################################
#不带头结点的链表
def RecursiveReverse(head):
#如果链表为空或只有一个元素
if head is None or head.next is None:
return head
else:
#反转后面的结点
newhead = RecursionReverse(head.next)
#把当前遍历的结点加到后面结点逆序后链表的尾部
head.next.next = head
head.next = None
return newhead
#带头结点的链表
def Reverse(head):
if head is None:
return
#获取链表的第一个结点
firstNode = head.next
#对链表进行逆序
newhead = RecursiveReverse(firstNode)
#头结点指向逆序后的第一个结点
head.next = newhead
return newhead
时间复杂度:O(N)
空间复杂度:O(N)
方法三:插入法
从链表的第二个结点开始,把遍历到的结点插入到头结点的后面,直至遍历结束。例如原链表为head->1->2->3->4->5->6->7,在遍历到2时,将其插入头结点后,链表变为
head->2->1->3->4->5->6->7,同理将后序遍历到的结点都插入head后。
########################################
#具体代码实现
########################################
def Reverse(head):
#判断链表是否为空
if head is None or head.next is None:
return
cur = None #当前结点
next = None #后继结点
cur = head.next.next
#设置链表第一个结点为尾结点
head.next.next = None
#把遍历到结点插入头结点后面
while cur is not None:
next = cur.next
cur.next = head.next
head.next = cur
cur = next
时间复杂度:O(N)
空间复杂度:O(1)