1.反转链表
public ListNode reversalList(){
ListNode cur = this.head;
ListNode curNext = null;
ListNode prev = null;
while (cur != null) {
curNext = cur.next;
cur.next = prev;
prev = cur;
cur = curNext;
}
return prev;
}
2.找到链表的中间节点,如果有两个节点,则返回第二个
//找到链表的中间节点,如果有两个节点,则返回第二个
public ListNode midList(){
ListNode slow = this.head;
ListNode fast = this.head;
while (fast != null && fast.next != null) {//条件顺序不能换 注意是并且
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
3.找倒数第K个节点
//找倒数第K个节点
public ListNode searchKi(ListNode head,int k){
if (k <= 0 || head == null ) {
return null;
}
ListNode slow = this.head;
ListNode fast = this.head;
while (k-1 != 0) {
fast = fast.next;
if (fast == null) {
System.out.println("没有这个节点!");
return null;
}
k--;
}
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
4.将两个有序链表合并为一个新的有序链表并返回
public static ListNode mergeTwoLists(ListNode headA,ListNode headB) {
ListNode newHead = new ListNode(-1);//新建一个虚拟头节点
ListNode tmp = newHead;
while (headA != null && headB != null) {
if (headA.val < headB.val) {
tmp.next = headA;
headA = headA.next;
} else {
tmp.next = headB;
headB = headB.next;
}
tmp = tmp.next;
}
if (headA != null) {
tmp.next = headA;
}
if (headB != null) {
tmp.next = headB;
}
return newHead.next;
}
调用结果:
public static void main(String[] args) {
MyLinkedList myLinkedList1 = new MyLinkedList();
myLinkedList1.addLast(1);
myLinkedList1.addLast(5);
myLinkedList1.addLast(7);
myLinkedList1.addLast(9);
MyLinkedList myLinkedList2 = new MyLinkedList();
myLinkedList2.addLast(3);
myLinkedList2.addLast(6);
myLinkedList2.addLast(10);
mergeTwoLists(myLinkedList1.head,myLinkedList2.head);
myLinkedList1.show();
}
5.给一定值X,将所有小于x的节点排在其余节点之前,且不能改变原来的数据顺序,返回排列后链表的头指针
public ListNode partition(ListNode pHead,int x) {
ListNode cur = pHead;
ListNode bs = null;
ListNode be = null;
ListNode as = null;
ListNode ae = null;
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;
}
//拼接起来 返回bs
if (bs == null) {
return as;
}
be.next = as;
//确保链表有尾
if (as != null) {
ae.next = null;
}
return bs;
}
}
6.有序链表中删除重复节点,重复的节点不保留,返回链表头指针
public ListNode deleteDuplication(ListNode pHead) {
ListNode newHead = new ListNode(-1);//新建一个虚拟头节点
ListNode tmp = newHead;
ListNode cur = pHead;
while (cur != null) {
if (cur.next != null && cur.val == cur.next.val) {
while (cur.next != null && cur.val == cur.next.val) {
cur = cur.next;
}
cur = cur.next;
} else {
tmp.next = cur;
tmp = tmp.next;
cur = cur.next;
}
}
tmp.next = null;
return pHead.next;
}
7.判断链表的回文结构
//7.判断链表的回文结构
public boolean judgeHuiwen(ListNode head){
ListNode slow = this.head;
ListNode fast = this.head;
//1.找中间节点
while (fast != null && fast.next!= null) {
fast = fast.next.next;
slow = slow.next;
}
//slow在中间位置
//2.中间节点之后的链表反转
ListNode cur = slow.next;
while (cur != null) {
ListNode curNext = cur.next;
cur.next = slow;
slow = cur;
cur = curNext;
}
//3.判断
while (this.head != slow) {
if (this.head.val != slow.val) {
return false;
}
//偶数情况
if (this.head.next == slow) {
return true;
}
this.head = this.head.next;
slow = slow.next;
}
return true;
}
8.相交链表
思路:
先求出差值步数,长链表先走差值步数,长短再一起走,直到相遇即pl=ps
//8.相交链表
public static ListNode getIntersectionNode(ListNode headA,ListNode headB){
ListNode pl = headA;
ListNode ps = headB;
int lenA = 0;
while (pl != null) {
lenA++;
pl = pl.next;
}
int lenB = 0;
while (ps != null) {
lenB++;
ps = ps.next;
}
pl = headA;
ps = headB;
int len = lenA - lenB;//差值步数
if (len < 0) {
pl = headB;
ps = headA;
len = lenB - lenA; //pl代表长链表,ps代表段链表
}
while (len != 0) {
pl = pl.next;
len--;
}
while (pl != null && ps!= null && pl != ps) {
ps = ps.next;
pl = pl.next;
}
if ( pl == ps && pl != null ) {
return pl;
}
return null;
}
调用:
//构造相交链表
public static void createCut(ListNode headA,ListNode headB){
headA.next.next = headB.next;
}
public static void main(String[] args) {
MyLinkedList myLinkedList1 = new MyLinkedList();
myLinkedList1.addLast(1);
myLinkedList1.addLast(5);
myLinkedList1.addLast(7);
myLinkedList1.addLast(9);
MyLinkedList myLinkedList2 = new MyLinkedList();
myLinkedList2.addLast(3);
myLinkedList2.addLast(6);
myLinkedList2.addLast(10);
createCut(myLinkedList1.head,myLinkedList2.head);
ListNode ret = MyLinkedList.getIntersectionNode(myLinkedList1.head,myLinkedList2.head);
System.out.println(ret.val);
结果:
9.判断链表中是否有环
思路:追及问题,一快一慢有环肯定会相遇,一个每次走一步,另一个每次走两步
public boolean hasCycle(ListNode head){
ListNode fast = this.head;
ListNode slow = this.head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
return true;
}
}
return false;
}
10.入环点
//10.返回链表开始入环的第一个节点,如果没有环,则返回null
public ListNode detectCycle(){
ListNode fast = this.head;
ListNode slow = this.head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
break;
}
}
if (fast == null ||fast.next == null) {
return null;//没有环
}
fast = this.head;
while (fast != slow) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
//创建一个链表环进行测试
public void createLoop(){
ListNode cur = this.head;
while (cur != null) {
cur = cur.next;
}
cur.next = head.next;
}