=======题目描述=======
题目链接:https://leetcode.com/problems/reverse-linked-list/
题目内容:
Reverse Linked List
Reverse a singly linked list.
Example:
Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL
=======算法实现=======
4种常用的单链表翻转的方法,分别是:开辟辅助数组,新建表头反转,就地反转,递归反转。
①开辟辅助数组:将单链表储存为数组,然后按照数组的索引逆序进行反转。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
'''
时间消耗O(n),空间消耗O(n)
'''
#边界条件
if head == None or head.next == None:
return head
#新建数组,用于保存链表各元素
Arr = []
#将链表元素赋值给数组
while head:
Arr.append(head.val)
head=head.next
#创建新的单链表
newHead = ListNode(0)
temp = newHead
#倒着读取数组元素赋值给链表
for i in Arr[::-1]:
#print(i)
temp.next=ListNode(i)
temp=temp.next
return newHead.next

②新建表头反转
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
'''
以单链表的第一个元素为循环变量cur,并设置2个temp辅助变量,保存数据;
时间消耗O(n),空间消耗O(1)
'''
#边界条件
if head == None or head.next == None:
return head
#定义循环变量
Cur=head
#定义保存数据的临时变量
temp = None
#创建新单链表的表头
newHead = None
while Cur:
temp=Cur.next
Cur.next = newHead
#每次更新新链表的表头
newHead = Cur
Cur=temp
return newHead

③就地反转:从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
'''
开始以单链表的第二个元素为循环变量,用2个变量循环向后操作,并设置1个 辅助变量tmp,保存数据;
时间消耗O(n),空间消耗O(1)
'''
#边界条件
if head == None or head.next == None:
return head
#定义循环变量1
p1=head
#定义循环变量2
p2=head.next
temp = None
while p2:
temp=p2.next
p2.next = p1
p1=p2
p2=temp
#将第一个节点挪到新表的表尾
head.next=None
return p1

④递归反转: (对于树的大部分问题,基本可以考虑用递归来解决。对于单链表的一些问题,也可以使用递归。可以认为单链表是一颗永远只有左(右)子树的树,因此可以考虑用递归来解决。或者说,因为单链表本身的结构也有自相似的特点,所以可以考虑用递归来解决)
1)如果head为空,或者只有head这一个节点,return head即可;
2)先遍历head->next为首的链表,得到一个头结点newHead;
3)把head赋值给head->next->next, head->next为空;
4)返回newHead。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
'''
递归操作,先将从第一个点开始翻转转换从下一个节点开始翻转
直至只剩一个节点
时间消耗O(n),空间消耗O(1)
'''
#边界条件
if head == None or head.next == None:
return head
else:
s = Solution()
#使用递归翻转
## 调用自身的反转函数,将头结点后数据当成一个完成的单链表处理
##上下两句是之前未运行成功的关键
newHead = s.reverseList(head.next)
#newHead = reverseList(head.next)
head.next.next=head
head.next=None
return newHead;

=======算法笔记->单链表=======
1.单链表(From BaiDu)
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

链表是动态分配存储空间的链式存储结构。
其包括一个“头指针”变量,其中第0个结点称为整个链表的头结点,头结点中存放一个地址,该地址指向一个元素,头结点一般不存放具体数据,只是存放第一个结点的地址。
链表中每一个元素称为“结点”,每个结点都由两部分组成:存放数据元素的数据域和存储直接后继存储位置的指针域。指针域中存储的即是链表的下一个结点存储位置,是一个指针。多个结点链接成一个链表。
最后一个结点的指针域设置为空(NULL),作为链表的结束标志,表示它没有后继结点。
使用结构体变量作为链表中的结点,因为结构体变量成员可以是数值类型,字符类型,数组类型,也可以是指针类型,这样就可以使用指针类型成员来存放下一个结点的地址,使其它类型成员存放数据信息。
当一个序列中只含有指向它的后继结点的链接时,就称该链表为单链表。
单链表的示意图如下:

Head指针为单链表的头指针,单链表的名字,也是其头指针。链表中的最后一个结点的指针域定义为空指针(NULL)。
2.单链表基本操作:
单链表的基本操作包含:创建,插入,删除,输出等
#python作为面向对象编程的,可以使用创建一个Node类来实现链表,利用类的属性引用来代替指针操作。
class Node(): # 初始化 构造函数
def __init__(self,value,next=None):
self.value=value
self.next=next
def Creatlist(n):
if n<=0:
return False
if n==1:
# 只有一个节点
return Node(1)
else:
root=Node(1)
tmp=root
# 一个一个的增加节点
for i in range(2,n+1):
tmp.next=Node(i)
tmp=tmp.next
# 返回根节点
return root
# 打印链表
def printlist(head):
p=head
while p!=None:
print p.value
p=p.next
# 链表长度
def listlen(head):
c=0
p=head
while p!=None:
c=c+1
p=p.next
return c
# 在n的前面插入元素
def insert(head,n):
if n<1 or n>listlen(head):
return
p=head
for i in range(1,n-1): # 循环m-2次到达 m-1
p=p.next
a=raw_input("Enter a value:")
t=Node(value=a)
t.next=p.next # 这里注意
p.next=t
return head # 把m放在t的后面 t放在原先p的后面
# 删除链表
def dellist(head,n):
if n<1 or n>listlen(head):
return head
elif n is 1:
head=head.next # 删除头
else:
p=head
for i in range(1,n-1):
p=p.next # 循环到达 2次
q=p.next
p.next=q.next # 把5放在3的后面
return head
代码实现参考
https://blog.csdn.net/fanyun_01/article/details/79831877
http://www.cnblogs.com/kuangsyx/p/9005174.html
https://segmentfault.com/a/1190000008453411
本文详细介绍了单链表的四种反转方法:开辟辅助数组、新建表头反转、就地反转和递归反转,并提供了每种方法的Python实现代码。同时,文章还概述了单链表的基本概念和操作。
461

被折叠的 条评论
为什么被折叠?



