查找单链表中倒数第k个节点。
思路:
1.编写一个方法,接收head节点,同时接收一个x
2.x表示是倒数第x个节点
3.先把链表从头到尾遍历,得到链表总长度
4.得到总长度后,我们从链表的第一个开始遍历(总长度-x)个,就可以得到我们需要的节点
public static void main(String[] args){
SingleLinkedListManger sllm = new SingleLinkedListManger();
System.out.println(getLength(sllm.getHead()));
}
/**
* 查找单链表中的倒数第k个节点
* 思路
* 1.编写一个方法,接受head节点,同时接收一个index
* 2.index表示是倒数第index个节点
* 3.先把链表从头到尾遍历,得到链表的总的长度getLength
* 4.得到size后,我们从链表的第一个开始遍历(size-index)个,就可以得到
* 5.如果找到了,则返回该节点,否则返回null
* @param head
* @param index
* @return
*/
public static SingleNode findLastIndexNode(SingleNode head,int x){
if (head.next == null){
return null;
}
//第一次遍历 获取链表长度(节点个数)
int size = getLength(head);
//第二次遍历 获取size - index位置,就是我们倒数的第k个节点
//先做一个index的校验
if (x <= 0 || x > size){
return null;
}
//定义一个辅助变量,for循环定位到倒数的index
SingleNode cur = head.next;
for (int i = 0; i < size-x; i++) {
cur =cur.next;
}
return cur;
}
public static int getLength(SingleNode head){
if (head.next == null){
return 0;
}
int length = 0;
SingleNode cur = head.next;
while (cur != null){
length++;
cur = cur.next;
}
return length;
}
class SingleLinkedListManger{
/**
* 先初始化一个头节点,头节点不要动,不存放具体数据
*/
private SingleNode head = new SingleNode("");
public SingleNode getHead(){
return head;
}
}
class SingleNode{
public String value;
public SingleNode next;
public SingleNode pre;
public SingleNode(String value){
this.value = value;
}
@Override
public String toString() {
return "SingleNode{" +
"value='" + value + '\''
'}';
}
}
单链表的反转
思路:
定义一个新的节点reverseHead=new CharacterNode();然后从头到尾遍历原来的链表,每遍历一个节点,就将其取出,放在新的链表reverseHead的最前端,最后将原来链表的头节点的next指向reverseHead的next实现反转。
public static void reverseList(CharacterNode head){
//如果但前链表为空,或者只有一个节点,无需反转,直接返回
if (head.next == null || head.next.next == null){
return;
}
CharacterNode cur = head.next;
CharacterNode next = null;
CharacterNode reverseHead = new CharacterNode(0,"","");
/**
* 遍历原来的链表,每遍历一个节点,就将将其取出,并放在新的链表reverseHead的最前端
*/
while (cur != null){
//先暂时保存当前节点的下一个节点,因为后面需要使用
next = cur.next;
//将cur的下一个节点指向新的链表的最前端
cur.next =reverseHead.next;
//将cur连接到新的链表上
reverseHead.next = cur;
//让cur后移
cur = next;
}
head.next =reverseHead.next;
}
单链表逆序
逆序和反转的区别是,逆序是在不该改变链表的结构的条件下进行输出。这种情况下我们可以使用栈这个数据结构,将各个节点压入到栈中,然后利用栈的先进后出的特点,就实现了逆序打印的效果。
public static void reversePrint(HeroNode head){
if (head.next == null){
return;
}
//创建一个栈,将各个节点压入栈
Stack<HeroNode> stack = new Stack<HeroNode>();
HeroNode cur = head.next;
//将链表的所有节点压入栈
while (cur != null){
stack.push(cur);
//将cur后移 这样就可以艳如下一个节点
cur = cur.next;
}
/**
* 出栈
*/
while (stack.size() > 0){
System.out.println(stack.pop());
}
}
合并两个有序的单链表,合并之后依然有序。
思路:创建一个新的节点,对两个链表的数据进行比较,按照顺序插入。
class ListNode{
int val;
ListNode next;
ListNode(int x){
val = x;
}
}
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
ListNode head = null;
if (l1.val <= l2.val){
head = l1;
head.next = mergeTwoLists(l1.next, l2);
} else {
head = l2;
head.next = mergeTwoLists(l1, l2.next);
}
return head;
}