专注Java教育14年 全国咨询/投诉热线:444-1124-454
星辉LOGO图
始于2009,口口相传的Java黄埔军校
首页 学习攻略 Java学习 Java实现链表反转的方法及步骤

Java实现链表反转的方法及步骤

更新时间:2022-12-13 12:28:48 来源:星辉 浏览910次

使用迭代方法反转链表

以下是迭代方法中涉及的一些步骤。

第 1 步:取三个指针(previous,current,next)。

前一个 = NULL,当前 = 头,下一个 = NULL。

第 2 步:使用循环遍历链表,并执行以下操作。

// 在改变当前的下一个之前,           
 // 保留下一个节点            
下一个 = 当前 -> 下一个           
// 现在改变当前的下一个            
// 这是反转发生的地方            
当前 -> 下一个 = 上一个            
// 将上一个和当前向前移动一步             
以前的 = 当前的           
当前 = 下一个   

执行

下面的代码显示了在上面定义的步骤的帮助下实现链表的反转。

文件名: LinkedListIterative.java

公共类 LinkedListIterative    
{    
// head是链表的第一个节点  
静态 LinkedListNode 头;    
// 创建链表节点的类  
// 链表的一个节点获取两个东西:一个是节点的值  
// other 是指向另一个节点的指针  
静态类 LinkedListNode    
{   
整 数值;   
接下来是LinkedListNode;   
// 类 LinkedListNode 的构造函数  
LinkedListNode(整数 编号)  
{  
瓦尔=没有;  
下一个= 空;  
}  
}    
// 反转链表的方法  
LinkedListNode reverse(LinkedListNode节点)  
{  
// 进行初始化   
// 按照定义的步骤   
LinkedListNode 前一个 =  null ;  
LinkedListNode 当前 = 节点;  
LinkedListNode next =  null ;      
while  (curr !=  null )   
{  
next = curr.next;  
当前.下一个=上一个;  
以前的=当前;  
当前=下一个;  
}  
节点=前一个;  
返回 节点;  
}    
//显示链表的内容  
void  printList(LinkedListNode nde)  
{  
while  (nde !=  null )   
{  
System.out.print(nde.val +  " " );  
nde = nde.next;  
}  
}    
// 主要方法  
public static void  main(String argvs[])    
{  
// 创建类 LinkedListIterative 的对象  
LinkedListIterative listObj =  new  LinkedListIterative();    
// 4 -> 空  
listObj.head =  new  LinkedListNode( 4 );    
// 4 -> 6 -> 空值  
listObj.head.next =  new  LinkedListNode( 6 );   
// 4 -> 6 -> 7 -> 空值  
listObj.head.next.next =  new  LinkedListNode( 7 );   
// 4 -> 6 -> 7 -> 1-> NULL  
listObj.head.next.next.next =  new  LinkedListNode( 1 );   
// 4 -> 6 -> 7 -> 1-> 5 -> NULL  
listObj.head.next.next.next.next =  new  LinkedListNode( 5 );    
// 4 -> 6 -> 7 -> 1-> 5 -> 8 -> NULL  
listObj.head.next.next.next.next.next =  new  LinkedListNode( 8 );   
// 4 -> 6 -> 7 -> 1-> 5 -> 8 -> 3 -> NULL  
listObj.head.next.next.next.next.next.next =  new  LinkedListNode( 3 );    
// 4 -> 6 -> 7 -> 1-> 5 -> 8 -> 3 -> 2 -> NULL  
listObj.head.next.next.next.next.next.next.next =  new  LinkedListNode( 2 );      
System.out.println( "反转前的链表为:" );  
listObj.printList(头);  
head = listObj.reverse(head);  
System.out.println( "\n" );  
System.out.println( "反转后链表为:" );  
listObj.printList(头);  
}  
}  

输出:

反转前的链表为:
4 6 7 1 5 8 3 2
反转后链表为:
2 3 8 5 1 7 6 4

时间和空间复杂度:上述程序的时间复杂度为 O(n),而空间复杂度为 O(1),其中 n 表示列表中存在的节点总数。

使用递归方法反转链表

以下是递归方法中涉及的一些步骤。

第 1 步:将给定的列表分成两部分 - 第一个节点和链表的其余部分。

第 2 步:为链表的剩余部分调用 reverseList() 方法。

第 3 步:将其余部分加入第一个。

第四步:固定头指针。

执行

下面的代码显示了在上面定义的步骤的帮助下实现链表的反转。

文件名: LinkedListRecursive.java

公共类 LinkedListRecursive    
{  
// 列表的第一个节点或头部  
静态 LinkedListNode 头;   
静态类 LinkedListNode    
{  
// 用于包含节点的值  
整 数值;    
// next 指针指向链表的另一个节点或 null  
接下来是LinkedListNode;   
// 类的构造函数  
链表节点(int  d)  
{  
// 赋值  
值=d;  
下一个= 空;  
}  
}    
// 实际发生列表反转的方法  
public  LinkedListNode reverseList(LinkedListNode head)  
{  
// 如果头部为空或列表  
// 只包含一个元素然后反转列表  
// 对列表没有任何影响。因此,我们   
// 不做任何操作就可以返回原来的列表  
如果 (head ==  null  || head.next ==  null )  
{  
返回 头;  
}    
// 反转列表的其余部分 (r) 并放置  
// 列表的第一个元素在最后   
LinkedListNode r = reverseList(head.next);  
head.next.next = 头;      
head.next =  null ;    
//固定头指针  
返回 r;  
}    
/* 显示链表的方法 */  
public void  printList(LinkedListNode h)   
{  
链表节点 t = h;  
while  (t !=  null )   
{  
System.out.print(t.val +  " " );    
// 移动到下一个节点  
t = t.下一个;  
}    
System.out.println();  
}      
// 主要方法  
public static void  main(String argvs[])    
{  
// 创建类 LinkedListRecursive 的对象  
LinkedListRecursive listObj =  new  LinkedListRecursive();    
// 4 -> 空  
listObj.head =  new  LinkedListNode( 4 );    
// 4 -> 6 -> 空值  
listObj.head.next =  new  LinkedListNode( 6 );    
// 4 -> 6 -> 7 -> 空值  
listObj.head.next.next =  new  LinkedListNode( 7 );    
// 4 -> 6 -> 7 -> 1-> NULL  
listObj.head.next.next.next =  new  LinkedListNode( 1 );    
// 4 -> 6 -> 7 -> 1-> 5 -> NULL  
listObj.head.next.next.next.next =  new  LinkedListNode( 5 );    
// 4 -> 6 -> 7 -> 1-> 5 -> 8 -> NULL  
listObj.head.next.next.next.next.next =  new  LinkedListNode( 8 );    
// 4 -> 6 -> 7 -> 1-> 5 -> 8 -> 3 -> NULL  
listObj.head.next.next.next.next.next.next =  new  LinkedListNode( 3 );    
// 4 -> 6 -> 7 -> 1-> 5 -> 8 -> 3 -> 2 -> NULL  
listObj.head.next.next.next.next.next.next.next =  new  LinkedListNode( 2 );      
System.out.println( "反转前的链表为:" );  
listObj.printList(头);  
head = listObj.reverseList(head);  
System.out.println( " " );  
System.out.println( "反转后链表为:" );  
listObj.printList(头);  
}  
}  

输出:

反转前的链表为:
4 6 7 1 5 8 3 2
反转后链表为:
2 3 8 5 1 7 6 4

时间和空间复杂度:上述程序的时间复杂度为 O(n),而空间复杂度为 O(1),其中 n 表示列表中存在的节点总数。请注意,由于递归,上述程序使用了内置堆栈。为了简单起见,我们忽略了内置堆栈占用的空间。

使用堆栈反转链表

下面是使用栈对链表进行反转时使用的步骤。

第 1 步:将节点的值保留在堆栈中,直到输入所有节点的值。

第 2 步:使用列表最后一个节点的值更新 Head 指针。

第 3 步:继续从堆栈中删除节点的值,并开始将它们附加到头节点,直到堆栈为空。

第 4 步:确保附加工作完成后,列表的最后一个节点指向 NULL。

执行

下面的代码显示了在上面定义的步骤的帮助下实现链表的反转。

文件名: LinkedListStack.java

// 重要的导入语句  
导入 java.util.*;   
公共类 LinkedListStack   
{    
// 列表的第一个节点或头部  
静态 LinkedListNode 头;     
静态类 LinkedListNode    
{  
// 用于包含节点的值  
整 数值;   
// next 指针指向链表的另一个节点或 null  
接下来是LinkedListNode;    
// 类的构造函数  
链表节点(int  d)  
{  
// 赋值  
值=d;  
下一个= 空;  
}  
}    
// 实际发生列表反转的方法  
public  LinkedListNode reverseList(LinkedListNode head, Stack<Integer> stk)  
{  
// 如果头部为空或列表  
// 只包含一个元素然后反转列表  
// 对列表没有任何影响。因此,我们   
// 不做任何操作就可以返回原来的列表  
如果 (head ==  null  || head.next ==  null )  
{  
返回 头;  
}    
// 遍历列表并放入节点的值  
//入栈stk  
while (head !=  null )  
{  
    stk.push(head.val);  
    head = head.next;  
}    
// head1 指的是反转的第一个节点   
// 链表  
链表节点 head1 =  null ;    
while (stk.empty() ==  false )   {  
如果(头== 空)  
{  
// 创建第一个节点  
// 反向链表  
head1 =  new  LinkedListNode(stk.peek());  
头=头1;  
stk.pop();  
}  
别的  
{  
// 创建反向的剩余节点   
// 链表  
head.next =  new  LinkedListNode(stk.peek());  
stk.pop();  
head = head.next;  
}      
}    
// 返回第一个节点   
// 反向链表  
返回 头1;  
}    
/* 显示链表的方法 */  
public void  printList(LinkedListNode h)   
{  
链表节点 t = h;  
while  (t !=  null )   
{  
System.out.print(t.val +  " " );    
// 移动到下一个节点  
t = t.下一个;  
}    
System.out.println();  
}    
// 主要方法  
public static void  main(String argvs[])    
{  
// 创建类 LinkedListStack 的对象  
LinkedListStack listObj =  new  LinkedListStack();    
// 4 -> 空  
listObj.head =  new  LinkedListNode( 4 );    
// 4 -> 6 -> 空值  
listObj.head.next =  new  LinkedListNode( 6 );    
// 4 -> 6 -> 7 -> 空值  
listObj.head.next.next =  new  LinkedListNode( 7 );    
// 4 -> 6 -> 7 -> 1-> NULL  
listObj.head.next.next.next =  new  LinkedListNode( 1 );    
// 4 -> 6 -> 7 -> 1-> 5 -> NULL  
listObj.head.next.next.next.next =  new  LinkedListNode( 5 );    
// 4 -> 6 -> 7 -> 1-> 5 -> 8 -> NULL  
listObj.head.next.next.next.next.next =  new  LinkedListNode( 8 );    
// 4 -> 6 -> 7 -> 1-> 5 -> 8 -> 3 -> NULL  
listObj.head.next.next.next.next.next.next =  new  LinkedListNode( 3 );    
// 4 -> 6 -> 7 -> 1-> 5 -> 8 -> 3 -> 2 -> NULL  
listObj.head.next.next.next.next.next.next.next =  new  LinkedListNode( 2 );    
// 创建 Stack 类的对象  
// 创建的栈将为空  
堆栈<整数> stk = 新 堆栈<整数>();    
System.out.println( "反转前的链表为:" );  
listObj.printList(头);    
head = listObj.reverseList(head, stk);  
System.out.println( " " );  
System.out.println( "反转后链表为:" );  
listObj.printList(头);    
}  
}  

输出:

反转前的链表为:
4 6 7 1 5 8 3 2
反转后链表为:
2 3 8 5 1 7 6 4

时间和空间复杂度:上述程序的时间复杂度为 O(n),而空间复杂度也是 O(n),其中 n 表示列表中存在的节点总数。

使用数组反转链表

以下是使用数组对链表进行反转时使用的步骤。

第 1 步:计算给定列表中存在的节点数。

第 2 步:创建一个整数数组,使数组的大小等于列表的大小。

第 3 步:遍历列表并使用节点的值从左到右填充数组。

第 4 步:从数组的末尾开始,逐个取出数组元素并从中创建一个列表,这样数组的最后一个元素构成列表的头部。数组的倒数第二个元素构成列表的第二个节点,依此类推。

执行

下面的代码显示了在上面定义的步骤的帮助下实现链表的反转。

文件名: LinkedListArray.java

// 重要的导入语句  
导入 java.util.*;    
公共类 LinkedListArray   
{    
// 列表的第一个节点或头部  
静态 LinkedListNode 头;     
静态类 LinkedListNode    
{  
// 用于包含节点的值  
整 数值;    
// next 指针指向链表的另一个节点或 null  
接下来是LinkedListNode;    
// 类的构造函数  
链表节点(int  d)  
{  
// 赋值  
值=d;  
下一个= 空;  
}  
}    
// 计算节点总数的方法   
//存在于链表中  
public int  countNodes(LinkedListNode 头)   
{  
// cnt 存储节点总数  
//存在于链表中  
int  cnt =  0 ;  
while (head !=  null )  
{  
// 计数加 1  
cnt = cnt +  1 ;    
// 将头部向前移动一步  
head = head.next;  
}    
返回 cnt;  
}    
// 实际发生列表反转的方法  
public  LinkedListNode reverseList(LinkedListNode head,  int  size)  
{  
// 用于存储链表节点值的数组  
int  arr[] =  new int [大小];     
// 循环填充数组  
for ( int  i =  0 ; i < 大小; i++)  
{  
arr[i] = head.val;  
head = head.next;  
}    
// i 存储数组 arr 的最后一个索引  
int  i = 大小 -  1 ;    
// head1 指的是链表的第一个节点  
链表节点 head1 =  null ;      
而(我> =  0 )  
{        
如果(head1 ==  null )  
{  
// 创建反向链表的第一个节点  
head1 =  new  LinkedListNode(arr[i]);  
头=头1;  
}  
别的  
{  
// 创建并追加剩余的节点   
// 反向链表的head1  
head.next =  new  LinkedListNode(arr[i]);  
head = head.next;  
}  
// 从头到尾迭代   
// 因此,将 i 减 1  
我 = 我 -  1 ;    
}    
// 返回第一个节点   
// 反向链表  
返回 头1;      
}      
/* 显示链表的方法 */  
public void  printList(LinkedListNode h)   
{  
链表节点 t = h;  
while  (t !=  null )   
{  
System.out.print(t.val +  " " );    
// 移动到下一个节点  
t = t.下一个;  
}    
System.out.println();  
}      
// 主要方法  
public static void  main(String argvs[])    
{  
// 创建类 LinkedListArray 的对象  
LinkedListArray listObj =  new  LinkedListArray();    
// 4 -> 空  
listObj.head =  new  LinkedListNode( 4 );    
// 4 -> 6 -> 空值  
listObj.head.next =  new  LinkedListNode( 6 );    
// 4 -> 6 -> 7 -> 空值  
listObj.head.next.next =  new  LinkedListNode( 7 );    
// 4 -> 6 -> 7 -> 1-> NULL  
listObj.head.next.next.next =  new  LinkedListNode( 1 );    
// 4 -> 6 -> 7 -> 1-> 5 -> NULL  
listObj.head.next.next.next.next =  new  LinkedListNode( 5 );   
// 4 -> 6 -> 7 -> 1-> 5 -> 8 -> NULL  
listObj.head.next.next.next.next.next =  new  LinkedListNode( 8 );    
// 4 -> 6 -> 7 -> 1-> 5 -> 8 -> 3 -> NULL  
listObj.head.next.next.next.next.next.next =  new  LinkedListNode( 3 );    
// 4 -> 6 -> 7 -> 1-> 5 -> 8 -> 3 -> 2 -> NULL  
listObj.head.next.next.next.next.next.next.next =  new  LinkedListNode( 2 );     
System.out.println( "反转前的链表为:" );  
listObj.printList(头);   
// size 是节点总数  
//存在于链表中  
int  size = listObj.countNodes(head);    
head = listObj.reverseList(head, size);  
System.out.println( " " );  
System.out.println( "反转后链表为:" );  
listObj.printList(头);    
}  
}  

输出:

反转前的链表为:
4 6 7 1 5 8 3 2
反转后链表为:
2 3 8 5 1 7 6 4

时间和空间复杂度:上述程序的时间复杂度为 O(n),而空间复杂度也是 O(n),其中 n 表示列表中存在的节点总数。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>