实现单链表的反序有2种方法
第一种:
用3个指针分别指向前中后然后改变结点的指向其实挺绕的在这我就不介绍这种方法了
第二种:
利用栈 把所有结点放到栈里边然后再把虚拟头节点指向栈顶第一个元素之后让站内元素连接起来即可实现单链表的逆序操作
代码:
public void reverse() {
// 指向链表
Node prev = dummyHead.next;
Stack<Node> stack = new Stack<>();
// 存入到栈中
while(prev!= null) {
stack.add(prev);
prev =prev.next;
}
// 如果栈不为空取出栈顶元素让虚拟右节点 和指针都指向栈顶元素
if (!stack.empty()) {
prev =dummyHead.next=stack.pop();
}
// 让指针依次连接剩下结点
while(!stack.empty()) {
prev.next=stack.peek();
prev=stack.pop();
}
}
链表的全部代码:
package demo;
import java.util.Stack;
public class LinkedList<E> {
// 成员内部类
private class Node {
E e;
Node next;
// 节点 构造方法的重构
public Node(E e, Node next) {
this.e = e;
this.next = next;
}
public Node(E e) {
this(e, null);
}
public Node() {
this(null, null);
}
// 重写 toString 方法
@Override
public String toString() {
// TODO Auto-generated method stub
return e.toString();
}
}
// 此处用的是虚拟头节点 会浪费一个空间
private Node dummyHead;
private int size;
public LinkedList() {
this.size = 0;
// 此处相当于为虚拟头节点 申请空间
// 用虚拟头节点 缺点是浪费一个空间 但是 查询插入删除等操作会非常方便
// 注意dummyHead = null 和 dummyHead = new Node(null,null) 是两个概念
this.dummyHead = new Node(null, null);
}
// 获取链表当前的大小
public int getSize() {
return size;
}
// 链表是否为空
public Boolean IsEmpty() {
return size == 0;
}
// 在指定位置处添加节点
public void add(int index, E e) {
// 此处要新建一个 Node 来寻找带插入位置
// 如果直接用dummyHead 会改变dummyHead 的位置
// 这样下次再操作 头就丢了整个链表就乱了 所以dummyHead 只负责指向头节点
Node prev = dummyHead;
if (index < 0 || index > size) {
System.out.println("非法操作");
} else {
for (int i = 0; i < index; i++) {
prev = prev.next;
}
Node node = new Node(e);
node.next = prev.next;
prev.next = node;
size++;
}
}
// 获取当前索引对应的节点
public E get(int index) {
if (index < 0 || index > size) {
System.out.println("非法操作");
return null;
}else {
Node prev = dummyHead;
for (int i = 0; i <= index; i++) {
prev =prev.next;
}
return prev.e;
}
}
// 链表是否存在当前节点
public Boolean contains(E e) {
Node prev = dummyHead.next;
for (; prev !=null; prev =prev.next) {
if (prev.e.equals(e)) {
return true;
}
}
return false;
}
// 删除当前位置元素
public E remove(int index) {
if (index <0 || index >size) {
System.out.println("非法操作");
return null;
}else {
Node prev = dummyHead;
for (int i = 0; i < index; i++) {
prev =prev.next;
}
Node node =prev.next;
prev.next = node.next;
node.next= null;
size--;
return node.e;
}
}
public void reverse() {
// 指向链表
Node prev = dummyHead.next;
Stack<Node> stack = new Stack<>();
// 存入到栈中
while(prev!= null) {
stack.add(prev);
prev =prev.next;
}
// 如果栈不为空取出栈顶元素让虚拟右节点 和指针都指向栈顶元素
if (!stack.empty()) {
prev =dummyHead.next=stack.pop();
}
// 让指针依次连接剩下结点
while(!stack.empty()) {
prev.next=stack.peek();
prev=stack.pop();
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Node prve = dummyHead.next;
for (; prve != null ; prve =prve.next) {
sb.append(prve +"->");
}
sb.append("NULL");
return sb.toString();
}
}
测试类:
package demo;
public class Test {
public static void main(String[] args) {
LinkedList<Integer> list =new LinkedList<>();
list.add(0, 5);
list.add(0, 4);
list.add(0, 3);
System.out.println("反序前");
for (int i = 0; i < list.getSize(); i++) {
System.out.print(list.get(i)+" ");
}
list.reverse();
System.out.println();
System.out.println("反序后");
for (int i = 0; i < list.getSize(); i++) {
System.out.print(list.get(i)+" ");
}
}
}