常用链表链及其必备操作
单链表的反转算法
思路分析
(1)遍历单链表,获取当前链表的当前结点curNode,并记录当前结点的下一个结点nextNode;
(2) 新建一个反转链表reverseHead,将当前结点curNode插入到reverseHead的最前面的结点(curNode.next=reverseHead.next;reverseHead.next=curNode)
(3) 只要当前链表没有遍历完成(curNode!=null),获取下一个结点为当前结点,重复执行Step1、Step2
代码
public void reverse(){
//链表为空或者只有一个结点,则不需要反转
if(head.next==null || head.next.next==null){
return ;
}
Node reverseHead=new Node(0);//反转结点的head指针;
Node cur=head.next;//指向原链表的当前结点
Node next=null;
while(cur!=null){
next= cur.next;// 记录当前结点的下一个结点
cur.next=reverseHead.next;
reverseHead.next=cur;
cur=next;
}
head=reverseHead;
}
获取链表中有效节点的个数(不包含头节点)
思路分析: 遍历链表,计数器加一即可
public int getLength(){
int count=0;
Node tmp=head.next;
while(tmp!=null){
count++;
tmp=tmp.next;
}
return count;
}
获取倒数第K个结点
思路分析: 首先获取该链表总的个数Count,则倒数第k个结点即为顺数第Count-k个结点
public Node getLastIndexNode(int k){
int count=getLength();
if(k>count){
return null;
}
Node tmp=head.next;
int index=1;
while(index <= count-k){
index++;
tmp=tmp.next;
}
return tmp;
}
合并两条有序的单链表,合并之后仍然是有序的
思路分析:
(1)设置两个指针tmp1和tmp2分别指向链表1和链表2
(2)依次比较两个大小,把小的增加到新链表的尾部直到循环退出;
(3)把其中一条没有完成的链表继续连接到tmp的尾部;
public Node mergeSingleLinkedList(Node head1,Node head2){
Node tmp1=head1.next;
Node tmp2=head2.next;
if(head1.next==null){
return head2;
}
if(head2.next==null){
return head1;
}
Node newHead=new Node(0);
Node tmp =newHead;
while(tmp1!=null && tmp2!=null){
if(tmp1.data>tmp2.data){
tmp.next=tmp2;
tmp=tmp2;
tmp2=tmp2.next;
}else{
tmp.next=tmp1;
tmp=tmp1;
tmp1=tmp1.next;
}
}
//上面的while循环跳出,必然是有一个先跳出循环
if(tmp1==null){
tmp.next=tmp2;
}else{
tmp.next=tmp1;
}
head=newHead;
return tmp;
}
双向链表
双向链表相对于单向链表的优点
(1)单向链表遍历时,只能先后遍历,而双向链表可以向前遍历
(2)双向链表可以实现自我结点的删除,而单向链表删除某个结点的时候,是删除当前结点的下一个结点
单向环形链表
josehu环问题
由n个结点围城一个环,编号为[1,n],从第k个结点(1<=k<=n)开始,从1开始计数,数到m的结点提取出来,然后再从该节点的下一个结点开始,又从1到m开始数,然后取出来,直到所有的节点都取出来为止,求被取出来的结点的顺序。
解决思路
josehu环问题:假设链环中有5个节点,从1节点开始数,数2次
算法实现步骤:
(1)创建joshu环(含有一个指向第一个节点的指针first)
(2)新建一个curNode指针,让其指向first的前一个结点(curNode.nextfirst)
(3)找到起始点,同时移动first和curNode指针,移动startNo-1次,此操作始终保持curNode.nextfirst
(4)开始数数,同时移动指针curNode和first的次数为:countNum-1次。
(5)判断curNode==first,如果成立,则进行(6),否则进行(7)
(6)此时环中只剩下最后一个结点,打印该结点信息即可
(7)删除first结点,即first=first.next;curNode.next=fist;继续执行(3)、(4)