单链表反转
// 单链表的反转
/*
1.定义一个节点 reverseHead 初始化为新的结点
2. 从头到尾遍历,每遍历一个就取出,放在新的链表的前端
3.遍历, 头插法
*/
public static void reverse(Node head){
// 如果为空或只有一个节点, 无需反转
if(head.next == null || head.next.next == null){
return;
}
// 不为空,需要遍历
Node cur = head.next;
Node next = null; // 定义一个结点指向 cur 的下一个结点
Node reversHead = new Node(0, " ");
// 遍历原来的链表,每遍历一个元素,取出
while(cur != null){
next = cur.next; // 先保存当前结点下一个结点,保证链表在取出一个节点后是连续的
cur.next = reversHead.next; //
reversHead.next = cur; // 将cur连接到新的链表上,永远放在头结点的后面
cur = next; // cur后移,保证继续遍历
}
head.next = reversHead.next;
}
逆序打印(栈)
// 逆序打印 单链表
/*
1.先反转 再打印(会破坏原来单链表的结构)
2.利用栈结构,将各个节点压入栈,利用栈的先进后出实现逆序打印
3.
*/
public static void reversePrintByStack(Node head){
if(head.next == null){
return;
}
Stack<Node> stack = new Stack<>();
Node cur = head.next;
// 将链表所有结点入栈
while (cur != null){
stack.push(cur);
cur = cur.next;
}
// 将栈中结点出栈打印
while(stack.size() > 0){
System.out.println(stack.pop()); // 先进后出
}
}
}
找到链表中倒数第k个结点
// 查找单链表的倒数第k个结点(新浪面试题)
/*
1.编写一个方法接受head结点,同时接受index
2.index表示倒数第index结点
3. 先把链表从头到尾遍历,得到链表总长
4.得到size后从链表第一个开始遍历,到 size- index个
*/
public static Node findLastIndex(Node head, int index){
if(head.next == null){
return null;
}
// 第一次遍历 得到链表个数
int size = getLength(head);
// 第二次遍历 到 size - index 个结点
// index是否合理
if(index > size || index < 0){
return null; // index不合法
}
// 遍历,定义辅助变量
Node temp = head.next;
for(int i = 0; i < (size - index); i++){
temp = temp.next;
}
return temp;
}
节点类
// 定义结点,每个node对象是一个节点
class Node{
public int no;
public String name;
public Node next;
public Node(int no, String name) {
this.no = no;
this.name = name;
}
@Override
public String toString() {
return "Node{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
}