更新时间:2022-12-13 12:28:48 来源:极悦 浏览1084次
以下是迭代方法中涉及的一些步骤。
第 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 表示列表中存在的节点总数。
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习