问题:
1.单链表反转:事先存好下一个节点再改变指针
2.链表中环的检测:快慢指针终会相遇
3.两个有序链表的合并:两个链表各一个指针,比较大小后加到最终的链表中(有点快排的感觉)
4.删除链表倒数第K个节点:转化为删除正数第length-K+1个节点
5.求链表的中间节点:快慢指针
思路都在代码的注释中,做链表的画张图就能更好的关注逻辑,比较直观,所以强烈建议画图来看看指针怎么走。
其中只在一种给出运行的例子,2345要运行验证在1的基础上改一改就好。
代码都已检验过没有问题,上代码:
1.单链表反转
//单链表反转
public class ListReverse {
public static void main(String[] args) {
ListNode node1=new ListNode(1);
ListNode node2=new ListNode(2);
ListNode node3=new ListNode(3);
ListNode node4=new ListNode(4);
ListNode node5=new ListNode(5);
ListNode node6=new ListNode(6);
node1.next=node2;
node2.next=node3;
node3.next=node4;
node4.next=node5;
node5.next=node6;
reverse(node1);
System.out.println(node6.next.val);
System.out.println(node5.next.val);
System.out.println(node4.next.val);
System.out.println(node3.next.val);
System.out.println(node2.next.val);
System.out.println(node1.next);
}
public static class ListNode{
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public static ListNode reverse(ListNode head){
//单链表反转
ListNode pre=null;
ListNode now=head;
ListNode next;
while (now!=null){
next=now.next;
now.next=pre;
pre=now;
now=next;
}
System.out.println("反转成功!");
return pre;
}
}
2.链表中环的检测
public class CircleInList {
/*
思路:快慢指针,如果有环,进入环以后,快慢指针一定会相遇,画图可验证
*/
public static boolean hasCircle(ListNode head){
//先做非空判断,只有一个元素也可以成环...
if (head==null){
return false;
}
//快慢指针
ListNode fast=head;
ListNode slow=head;
while (fast!=null){
fast=fast.next.next;
slow=slow.next;
//先走了再判断
if (fast==slow){
return true;
}
System.out.println("走了一次");
}
return false;
}
}
3.两个有序链表的合并
//合并两个有序列表
public class ListMerge {
/*
思路:两个list各一个指针,比较大小,小的放到新的list中
当有一个遍历完,则把另一个的剩下的全都加到result这个list中
*/
public static ListNode merge(ListNode head1, ListNode head2) {
if (head2 == null || head1 == null) {
System.out.println("其中有一个List为空");
return null;
}
ListNode ResultHead = null;
ListNode current = null;
ListNode Point1 = head1;
ListNode Point2 = head2;
//得到头节点
if (Point1.val < Point2.val) {
ResultHead = Point1;
Point1 = Point1.next;
} else {
ResultHead = Point2;
Point2 = Point2.next;
}
current = ResultHead;
while (Point1 != null && Point2 != null) {
if (Point1.val < Point2.val) {
current.next = Point1;
Point1 = Point1.next;
} else {
current.next = Point2;
Point2 = Point2.next;
}
current = current.next;//当前下标往后移动一个
System.out.println("合并一次");
}
if (Point1 == null) {
current.next = Point2;
System.out.println("后面的都合并进去");
} else {
current.next = Point1;
System.out.println("后面的都合并进去");
}
return ResultHead;
}
}
4.删除链表倒数第K个节点
//删除倒数第K个node
public class deleteNode {
//转化为删除正数length-K+1
public static void deleteNode(ListNode head, int K){
if (head==null){
System.out.println("请勿传入空节点");
return;
}
int length=1;
int count=1;
int deleteNumberChanged=0;
ListNode point=head;
while(point.next!=null){
point=point.next;
length++;
}
if (length<K){
System.out.println("没这么多数字");
return;
}
deleteNumberChanged=length-K+1;
point=head;
while (point.next!=null){
if (count+1==deleteNumberChanged){
ListNode temp=point.next;
point.next=null;
point.next=temp.next;
System.out.println("删除成功");
break;
}
point=point.next;
count++;
System.out.println("往后查找");
}
}
}
5.求链表的中间节点
//得到链表的中点
public class getMiddleNode {
public static ListNode getMiddleNode(ListNode head){
if (head==null){
return null;
}
/*思路:快慢指针,快的走两步,慢的走一步
*/
ListNode fast=head;
ListNode slow=head;
while(fast.next!=null&&fast.next.next!=null){
fast=fast.next.next;
slow=slow.next;
}
return slow;
}
}