LeetCode: Reverse Linked List 单链表的反转

本文详细介绍了单链表的四种反转方法:开辟辅助数组、新建表头反转、就地反转和递归反转,并提供了每种方法的Python实现代码。同时,文章还概述了单链表的基本概念和操作。

=======题目描述=======

题目链接: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

https://www.cnblogs.com/leaver/p/6718421.html

https://www.cnblogs.com/wft1990/p/6718623.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值