链表种类及其常用操作

常用链表链及其必备操作

单链表的反转算法

思路分析
(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.next
first
(4)开始数数,同时移动指针curNode和first的次数为:countNum-1次。
(5)判断curNode==first,如果成立,则进行(6),否则进行(7)
(6)此时环中只剩下最后一个结点,打印该结点信息即可
(7)删除first结点,即first=first.next;curNode.next=fist;继续执行(3)、(4)

原文地址:https://www.cnblogs.com/Thinker-Bob/p/13027284.html