当前位置: 首页 > wzjs >正文

住宅和城乡建设部网站深圳网站建设公司fantodo

住宅和城乡建设部网站,深圳网站建设公司fantodo,西安百度seo推广电话,网站商城与网站区别吗链表是一种常见的数据结构,广泛应用于各种算法和程序设计中。反转链表是一个经典的面试题,也是理解递归和链表操作的好例子。本文将详细介绍如何使用递归方法在Java中反转链表,并逐步解析其背后的原理。 链表介绍 链表由一系列节点组成&…

_20250225223348.jpg

链表是一种常见的数据结构,广泛应用于各种算法和程序设计中。反转链表是一个经典的面试题,也是理解递归和链表操作的好例子。本文将详细介绍如何使用递归方法在Java中反转链表,并逐步解析其背后的原理。

链表介绍

链表由一系列节点组成,每个节点包含两个部分:

  1. 数据域:存储节点的值。

  2. 指针域:指向下一个节点的引用。

在Java中,链表节点一般用以下类表示:

public class ListNode {int val;ListNode next;public ListNode(int val) {this.val = val;}
}

递归介绍

递归是一种通过函数调用自身来解决问题的方法。它将复杂问题分解为更小的子问题,直到子问题可以直接解决为止。每次递归调用都会在栈中创建一个新的栈帧,保存当前状态。递归结束时,栈帧依次弹出,恢复到上一层调用。

递归的基本要素:

  • 基线条件(Base Case):递归终止的条件,防止无限递归。

  • 递归条件(Recursive Case):将问题分解为更小的子问题,并调用自身。

反转链表

反转链表通常由迭代和递归两种方法,迭代比较简单、直接。递归实现代码就比较简洁。

递归反转链表的基本思路是将当前节点的next指针指向前一个节点,然后递归地对下一个节点进行同样的操作。递归的核心思想是将问题分解为更小的子问题,直到达到基本情况(通常是链表末尾)。

我们分以下三种常用情况进行示例。

递归反转整个链表

实现代码如下:

/*** 反转整个链表*/
public class ReverseAll {/*** 递归实现* @param head* @return*/public static ListNode reverseRec(ListNode head) {// 基本情况:链表为空或只有一个节点if (head == null || head.next == null) {return head;}// 递归反转剩余部分ListNode last = reverseRec(head.next);// 将当前节点的下一个节点的next指针指向当前节点head.next.next = head;// 将当前节点的next指针置为nullhead.next = null;return last;}/*** 迭代实现* @param head* @return*/public static ListNode reverseIte(ListNode head) {// 链表为空或只有一个节点,则返回该节点if (head == null || head.next == null) {return head;}ListNode pre = null;ListNode cur = head;// 遍历链表while (cur != null) {// 记录当前节点的下一个节点ListNode next = cur.next;// 反转当前节点的指针cur.next = pre;// 移动prev到当前节点pre = cur;// 移动curr到下一个节点cur = next;}return pre;}public static void main(String[] args) {ListNode head1 = new ListNode(1);ListNode head2 = new ListNode(2);ListNode head3 = new ListNode(3);ListNode head4 = new ListNode(4);head1.next = head2;head2.next = head3;head3.next = head4;head4.next = null;ListNode reverse = reverseRec(head1);//ListNode reverse = reverseIte(head1);while (reverse != null) {System.out.println(reverse.val);reverse = reverse.next;}}
}

其核心思想是递归找到链表的最后一个节点,利用递归结束栈帧依次弹出,恢复到上一层调用的特性,将链表从后一次将指针指向前一个元素,实现链表的反转。

反转链表前N个节点

实现反转链表的前N个节点,在上一个实现的基础上将基线条件变为 n==1,同时需要记录后驱节点successor,并将原来head的后驱节点设置为successor;

实现代码如下:

/*** 反转链表的前N个节点*/
public class ReverseFront {/*** 递归实现* @param head* @return*///记录不需要反转的头节点public static ListNode successor=null;public static ListNode reverseRec(ListNode head,int n) {// 记录后半部分的起始节点,并返回新的头节点if (n == 1) {successor = head.next;return head;}// 以head.next为起点,反转前n-1个节点(每多一次递归,则反转的节点少一个)ListNode last = reverseRec(head.next,n-1);// 将当前节点的下一个节点的next指针指向当前节点head.next.next = head;// 将当前节点的next指针置为后驱节点head.next = successor;return last;}/*** 迭代实现* @param head* @return*/public static ListNode reverseIte(ListNode head,int n) {// 链表为空或只有一个节点,则返回该节点if (head == null || head.next == null) {return head;}ListNode pre = null;ListNode cur = head;ListNode successor=null;int i = 1;// 遍历链表while (i <= n) {// 记录当前节点的下一个节点ListNode next = cur.next;// 反转当前节点的指针cur.next = pre;// 移动prev到当前节点pre = cur;// 移动curr到下一个节点cur = next;//记录后半部分的其实节点successor = next;i++;}//将反转之后的前半部分链表的next指针指向后半部分链表head.next = successor;return pre;}public static void main(String[] args) {ListNode head1 = new ListNode(1);ListNode head2 = new ListNode(2);ListNode head3 = new ListNode(3);ListNode head4 = new ListNode(4);head1.next = head2;head2.next = head3;head3.next = head4;head4.next = null;ListNode reverse = reverseRec(head1,2);//ListNode reverse = reverseIte(head1,2);while (reverse != null) {System.out.println(reverse.val);reverse = reverse.next;}}
}

反转链表区间[m,n]中的元素

/*** 反转链表区间[m,n]中的元素*/
public class ReverseSection {/*** 递归实现* @param head* @return*///记录不需要反转的头节点public static ListNode successor=null;public static ListNode reverseRecN(ListNode head,int n) {// 记录后半部分的起始节点,并返回新的头节点if (n == 1) {successor = head.next;return head;}// 以head.next为起点,反转前n-1个节点(每多一次递归,则反转的节点少一个)ListNode last = reverseRecN(head.next,n-1);// 将当前节点的下一个节点的next指针指向当前节点head.next.next = head;// 将当前节点的next指针置为后驱节点head.next = successor;return last;}/*** 递归实现* @param head* @return*/public static ListNode reverseRec(ListNode head,int m,int n) {//m如果==1,则说明需要反转前n个节点if(m == 1){return reverseRecN(head,n);}// 前进到反转的起点触发基线线条件head.next = reverseRec(head.next,m-1,n-1);return head;}/*** 迭代实现* @param head* @return*/public static ListNode reverseIte(ListNode head,int m,int n) {// 链表为空或只有一个节点,则返回该节点if (head == null || head.next == null) {return head;}ListNode pre = null;ListNode cur = head;ListNode nodem1=null;ListNode nodem=null;int i = 1;// 遍历链表while (i <= n ) {// 记录当前节点的下一个节点ListNode next = cur.next;//记录m-1位置的节点if(i == m-1){nodem1=cur;}//记录m位置的节点if(i == m){nodem=cur;}//反转区间中的元素if(i>=m){// 反转当前节点的指针cur.next = pre;}// 移动prev到当前节点pre = cur;// 移动curr到下一个节点cur = next;if(i == n){//将反转区间的第一个元素的指针指向后半部分链表nodem.next = next;//将半部分链表的指针指向反转区间的最后一个元素nodem1.next = pre;}i++;}return head;}public static void main(String[] args) {ListNode head1 = new ListNode(1);ListNode head2 = new ListNode(2);ListNode head3 = new ListNode(3);ListNode head4 = new ListNode(4);head1.next = head2;head2.next = head3;head3.next = head4;head4.next = null;ListNode reverse = reverseRec(head1,2,4);//ListNode reverse = reverseIte(head1,2,4);while (reverse != null) {System.out.println(reverse.val);reverse = reverse.next;}}
}

复杂度分析

  • 时间复杂度

不管时递归还是迭代,都只需要循环或者迭代n次就可以完成反转,所以时间复杂度都是O(n),

  • 空间复杂度

迭代解法的空间复杂度是O(1),而递归需要堆栈,空间复杂度是O(n);

  • 选择建议

如果链表较短且代码简洁性更重要,可以选择递归方法。

如果链表较长或需要优化空间效率,优先选择迭代方法。

总结

递归反转链表是一个经典的算法问题,通过递归方法可以简洁地实现链表的反转。理解递归的关键在于将问题分解为更小的子问题,并正确处理基本情况。希望本文能帮助你更好地理解递归和链表操作,并在实际编程中灵活运用。

http://www.dtcms.com/wzjs/839132.html

相关文章:

  • 滁州做网站公司什么平台可以接国外订单
  • 网站浮动窗口怎么做贵州省住房和城乡建设厅网网站首页
  • 高级网站设计效果图新乡网络公司推荐
  • 机关网站建设工程总结做兼职的网站有哪些工作内容
  • 网站建设企业咨询网页设计这个行业怎么样
  • 山东联通网站备案免费软件库下载
  • wordpress 友情链接 nofollow网站建设 优化
  • 建设工程 质量 协会网站网站最合适的字体大小
  • vue适合做门户网站吗建设外贸网站
  • 个人怎样免费建网站vps 做镜像网站
  • 南阳网站设计北京建设银行官方网站
  • 漳州手机网站建设公司哪家好免费漫画app推荐
  • 品牌的宣传及推广石家庄全网seo
  • 支付网站建设推广的会计分录阳性最新消息
  • 手机在线网站小说代理平台
  • 聊城 网站建设深圳 福田网站建设
  • 海外网站加速器下载爱站网收录
  • 谢岗网站仿做平面设计师磨刀石
  • 网站搜索引擎优化公司中国建设人才服务信息网官网
  • 营销型网站建设的指导原则wordpress 搜索分类
  • 专业SEO教程网站网站建设与管理就业前景
  • 外国排版网站昆明搜索引擎的关键词优化
  • 商务贸易网站建设临淄信息网港
  • 贵阳网站设计报价本地搭载wordpress
  • 南阳网站建设的公司如何自建一个便宜的网站
  • php网站建设案例教程电子邮箱免费注册
  • 网站设计中的技术分析建设银行网站怎么设置转账额度
  • 廊坊商昊网站建设网站设计制作要多少钱
  • 国内外网站网站广州自适应网站建设
  • 网站域名登陆地址网站用什么切版