常见题目
1.求单链表中有效节点的个数
getLength方法
/**
* 统计单链表的节点的个数(不计算头节点)
*
* @param head 链表的头节点
* @return 有效节点的个数
*/
public static int getLength(HeroNode head) {
//空链表则返回长度为0
if (head.next == null) {
return 0;
}
int length = 0;
HeroNode cur = head.next;
while (cur != null) {
length++;
//遍历
cur = cur.next;
}
return length;
}
测试
//测试一下求单链表中有效节点的个数
System.out.println("有效节点的个数为:"+getLength(singleLinkedList.getHead()));
2.查找单链表中倒数第k个节点
首先遍历一遍,得到链表的总长度size,然后再正序遍历(size-index)得到倒数第index个节点
/**
* 查找单链表中倒数第k个节点
* 首先遍历一遍,得到链表的总长度size,然后再正序遍历(size-index)得到倒数第index个节点
*
* @param head 链表头节点
* @param index 倒数第index个节点
* @return 返回倒数第index个节点
*/
public static HeroNode findLastNode(HeroNode head, int index) {
if (head == null) {
return null;
}
//得到链表的长度
int size = getLength(head);
//数据校验
if (index > size || index <= 0) {
return null;
}
//定义辅助变量
HeroNode targetNode = head.next;
for (int i = 0; i < size - index; i++) {
targetNode = targetNode.next;
}
return targetNode;
}
测试
//测试一下查找单链表中倒数第k个节点
int index = -1;
System.out.printf("倒数第%d个节点:" + findLastNode(singleLinkedList.getHead(), index), index);
3.单链表的反转
创建一个新的链表来实现反转
/**
* 单链表的反转
*
* @param head
* @param newSingleLinkedlist
*/
public static void reverseNode(HeroNode head, SingleLinkedList newSingleLinkedlist) {
int size = getLength(head);
HeroNode newHead = newSingleLinkedlist.getHead();
for (int i = 1; i <= size; i++) {
newHead.next = findLastNode(head, i);
newHead = newHead.next;
}
newHead.next = null;
}
//测试单链表的反转
SingleLinkedList newLinkedList = new SingleLinkedList();
reverseNode(singleLinkedList.getHead(), newLinkedList);
System.out.println("反转后的单链表:");
newLinkedList.list();
在原来的链表中实现链表反转。
/**
* 不创建新的链表就实现反转的方法
* @param head
*/
public static void reverseList(HeroNode head){
//如果当前链表为空,或者只有一个节点,则无需反转
if (head.next == null || head.next.next == null) {
return;
}
//使用两个指针来遍历原来的节点,cur和next指向原来的链表
HeroNode cur = head.next;
HeroNode next = null;
HeroNode reverseHead = new HeroNode(0, "", "");
//遍历原来的链表,每遍历一个节点,就将其取出,放在新的链表reverseHead的最前端
while (cur != null) {
next = cur.next;
cur.next = reverseHead.next;
reverseHead.next = cur;
cur=next;
}
//将head.next 指向reverseHead.next,实现单链表的反转
head.next=reverseHead.next;
}
测试反转的代码
//测试单链表的反转2
System.out.println("再次反转后的单链表:");
reverseList(singleLinkedList.getHead());
singleLinkedList.list();
4.从尾到头打印单链表
- 方式1:可以将链表反转,再逆序打印
- 方式2:利用栈,将各个节点压入栈中,利用先入后出的特性,实现逆序打印
简单测试一下栈的特性
package linkedlist;
import java.util.Stack;
public class TestStack {
public static void main(String[] args) {
Stack<String> stack = new Stack<>();
//入栈
stack.add("jack");
stack.add("tom");
stack.add("smith");
//出栈
while (stack.size() > 0) {
//pop()就是将栈顶元素取出。
System.out.println(stack.pop());
}
}
}
smith
tom
jack
逆序打印单链表
/**
* 测试逆序打印单链表
* @param head
*/
public static void reversePrint(HeroNode head) {
//空链表,不能答应
if (head.next == null) {
return;
}
//创建一个栈,将各个节点压入
Stack<HeroNode> stack = new Stack<>();
HeroNode cur = head.next;
//将链表全部节点压入栈中
while (cur != null) {
stack.push(cur);
//cur后移,可以将下一个节点压入
cur = cur.next;
}
while (stack.size() > 0) {
//栈的特点,先进后出
System.out.println(stack.pop());
}
}
测试逆序打印
//测试逆序打印单链表
System.out.println("测试逆序打印单链表");
reversePrint(singleLinkedList.getHead());
5.合并两个有序单链表,合并之后的链表依然有序