一 打印两个有序链表的公共部分
给定两个有序链表的头指针head1和head2,打印两个链表的公共部分。
package 打印链表公共部分;//有序链表
public class Node {
public int info;
public Node link;
public Node(int data){
this.info=data;
}
public void printNode(Node head1,Node head2){
while(head1!=null&&head2!=null){
//如果head1的值小于head2,则head1往下移动
if(head1.info<head2.info){
head1=head1.link;
}
//如果head2的值小于head1,则head2往下移动
else if(head1.info>head2.info){
head2=head2.link;
}
//若二者的值相等,则打印出来,并将head1和head2都往下移动
else{
System.out.println(head1.info);
head1=head1.link;
head2=head2.link;
}
}
}
}
二 删除单链表中倒数第K个节点
实现一个函数,可以删除单链表中倒数第K个节点
package 删除倒数第K个节点;
public class Node {
public int value;
public Node next;
public Node cur;
public Node(int data){
this.value=data;
}
public void printNode(Node head,int k){
cur=head;
//while循环结束时,若k大于0,则说明不存在倒数第k个数
while(cur!=null){
cur=cur.next;
k--;
}
if(k<=0){
//k=0说明k等于链表的节点数
if(k==0){head=head.next;}
else{
cur=head;
//++k=0时,cur恰好代表要删除的节点的前一个节点
while(++k!=0){
cur=cur.next;
}
cur.next=cur.next.next;
}
}
}
}
三 删除链表的中间节点
实现一个函数,删除链表中间节点,例如
1 不删除任何节点
1→ 2删除节点1
1→ 2→ 3删除节点2
1→ 2→ 3→ 4删除节点2
1→2→3→4→ 5删除节点3
package 删除链表中间节点;
public class Node {
public int value;
public Node next;
public Node(int data){
this.value=data;
}
//head为首节点,num为节点数
public void removeMid(Node head,int num){
Node cur=head;
//找到中心节点的位置
if(num==1)return;
else if(num==2)head=null;
else if(num%2==1)num=(num+1)/2;
else num=num/2;
while(num>2){
cur=cur.next;
num--;
}
cur.next=cur.next.next;
}
}<strong>
</strong>
四 反转单向链表
实现反转单向链表的函数
package 反转单向链表;
public class Node {
public int value;
public Node link;
public Node(int data){
this.value=data;
}
public void reverseList(Node head){
Node p1=head;
Node p2=head.link;
Node p3=null;
while(p2!=null){
p3=p2.link;//保留p2.link以便下次循环用
p2.link=p1;//将p1赋给p2.link,链表反转,p2.link将指向p1
/*
* p2赋给p1
* p3赋给p2
* 循环后移一位
*/
p1=p2;
p2=p3;
}
//重新定义头节点
head=p1;
}
}
五 环形单链表的约瑟夫问题
约瑟夫环的相关问题,可参照我的另一篇博客约瑟夫环问题详述
输入:一个环形单链表头节点head和报数的值num
返回:最后生存下来的节点,且这个节点自己组成环形单链表,其他节点都删掉
package 环形单链表的约瑟夫问题;
/*
* 没删除一个节点,都要遍历m次,一共需要删除的节点数为n-1,
* 故该解法的时间复杂度为O(n×m)
*/
public class Node {
public int value;
public Node next;
public Node(int data){
this.value=data;
}
public Node killOne(Node head,int num){
if(head==null||head.next==head||num<1){
return head;
}
Node last=head;
//while语句将last引用指向head节点的前一个节点
while(last.next!=head){
last=last.next;
}
int count=0;
while(last!=head){
if(++count==num){
last.next=head.next;//head.next此时相当于last.next.next,起到删除节点的作用
count=0;
}else{
last=last.next;//last引用的指向向后移动
}
head=last.next;//head引用始终指向last节点的下一个节点
}
return head;
}
}