1 反转一个单链表。给一个单链表的头节点head,反转链表,并返回反转后的链表
package linkedlistdemo;
class ListNode {//节点
public int val;
public ListNode next;//类型是Node
public ListNode(int val){
this.val=val;
}
}
public class SingleLinkedList {
public ListNode head;//head是链表SingleLinkedList的头,不是节点Node的头
public int usedSize;//记录当前链表中节点的个数
public Node reverseList(){
//没有节点
if(this.head==null){
return null;
}
//只有一个头节点
else if(this.head.next==null){
return this.head;
}
//最起码有两个节点以上
Node cur=this.head.next;
this.head.next=null;
while(cur !=null) {
Node curNext=cur.next;
cur.next=this.head;
this.head=cur;
cur=curNext;
}
return this.head;
}
}
2 给定一个带有头节点head的非空单链表,返回链表的中间节点。如果有两个中间节点,则返回第二个中间节点。(只遍历链表一边)
定义两个引用,fast和slow,它们的起始位置都在头节点处,fast向后走的速度是slow的二倍,即fast每走两步slow走一步。
(1)有奇数个节点:当fast.next!=null时,就说明fast走到了尾部,此时slow所在的位置就是中间位置。
(2)有偶数个节点:当fast!=null时,此时fast不是一个节点,slow所在的位置就是中间位置。
package linkedlistdemo;
class ListNode {//节点
public int val;
public ListNode next;//类型是Node
public ListNode(int val){
this.val=val;
}
}
public class SingleLinkedList {
public ListNode head;//head是链表SingleLinkedList的头,不是节点Node的头
public int usedSize;//记录当前链表中节点的个数
public ListNode middleNode(){
ListNode fast=this.head;
ListNode slow=this.head;
while(fast.next!=null && fast!=null){
fast=fast.next.next;
slow=slow.next;
}
return slow;
}
}
3 输入一个链表,输出该链表中倒数第k个节点(只遍历链表一遍)
定义两个引用,fast和slow,它们的起始位置都在头节点处。fast先走k-1步,再让fast和slow同时移动,当fast所处位置为最后一个节点时,slow所处位置就是倒数第k个节点的位置。
package linkedlistdemo;
class ListNode {//节点
public int val;
public ListNode next;//类型是Node
public ListNode(int val){
this.val=val;
}
}
public class SingleLinkedList {
public ListNode head;
public ListNode findKthToTail(int k){
//k是否是合法的
if(k<=0 || head==null){
return null;
}
ListNode fast=head;
ListNode slow=head;
while (k-1>0){
if(fast.next==null){
return null;
}
fast=fast.next;
k--;
}
while(fast.next!=null){
fast=fast.next;
slow=slow.next;
}
return slow;
}
}
4 将两个有序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
package linkedlistdemo;
public class TestDemo {
//将两个有序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的
public static ListNode mergeTwoLists(ListNode head1,ListNode head2){
ListNode newNode=new ListNode(-1);//虚拟节点,数据不具备意义
ListNode tmp =newNode;
while(head1.val<head2.val){
if (head1.val<head2.val) {
tmp.next = head1;
tmp = tmp.next;
head1 = head1.next;
}else {
tmp.next = head2;
tmp = tmp.next;
head2 = head2.next;
}
}
if(head1!=null){
tmp.next=head1;
}
if(head2!=null){
tmp.next=head2;
}
return newNode.next;
}
}
ListNode newNode=new ListNode(-1);//虚拟节点,数据不具备意义
5 现有一链表的头指针ListNode*pHead,给定值x,编写代码所有小于x的节点排在大于或等于x的节点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。
package linkedlistdemo;
class ListNode {//节点
public int val;
public ListNode next;//类型是Node
public ListNode(int val){
this.val=val;
}
}
public class SingleLinkedList {
public ListNode head;
public ListNode partition(ListNode pHead,int x){
if(pHead==null){
return null;
}
ListNode bs=null;
ListNode be=null;
ListNode as=null;
ListNode ae=null;
ListNode cur=pHead;
while (cur!=null){
if(cur.val<x){
if(bs==null){
bs=cur;
be=cur;
}else{
be.next=cur;
be=be.next;
}
}else {
//是不是第一次插入
if(as==null){
as=cur;
ae=cur;
}else {
ae.next=cur;
ae=ae.next;
}
}
cur=cur.next;
}
if(bs==null){
return as;
}
be.next=as;
//检查最后一段是不是有数据,如果有,那么我们需要进行把最后一个节点的next置为空,否则会出现死循环
if(as!=null){
ae.next=null;
}
return bs;
}
}