单链表的反转

单链表的反转


单链表概念引入

image_1clvsa7hnor618ka1t8hpjj1emm9.png-7.2kB
有一个空的head节点作为头节点,头节点的存在主要是为了操作的统一性而设立的(删除增添节点等操作能够统一,不需要特殊考虑单独情况),当然它不是必须的,它的数据域毫无意义。


我们的目标:实现单链表的反转
image_1cm2jnik8qfhsjc5frcqlkki2m.png-7.2kB
1.如果考虑不破化原有链表,实现单链表翻转。这个实现比较简单,主要考虑在复杂度上,如果每次都取最后一个元素再插入新的链表,那么每次都要从头开始遍历一遍,复杂度为O(n2),但是我们可以考虑循环一遍将元素放入栈中,然后弹出实现反转。

2.在原有结构上实现反转。
最理想的方法当然是遍历过去一遍实现,要怎么办?

思路:
如果只有只有一个元素,不用操作;
如果多于一个元素,我们考虑到如果直接让后一个元素的next域指向前一个元素,那么再后一个元素的位置我们就无法确定,所以在将后一个元素的next指向前一个元素之前,我们将原本的next的指向元素保存就可以了。

看示例图:
image_1cm2kjn80172e1gibrt87t413pg40.png-9.3kB
我们借助两个移动的游标来完成工作,每次要改变 cursor2.next 的方向前,我们先用tmp保存好原来的cursor2.next指向的元素。
这样当cursor2.next完成赋值后:
image_1cm2krnjj1n5a1fbf1v371kiu19224t.png-9.8kB
我们记录了tmp的位置,之后两个cursor同时移动:
image_1cm2mbaepo93192i8fl1gjqf1g67.png-9.7kB
重复操作:
image_1cm2mfir91v5oq8bqi112mk1f2i6k.png-9.8kB
通过这个方法,我们就可以实现两个cursor的移动,实现迭代。
最后当tmp为空,循环截止;

实现代码:   
    public void reverse(){
    if(size==1) return ;
    int count=0;
    Node cursor1=root.next;
    Node cursor2=cursor1.next;
    while(cursor2.next!=null){
        Node tmp=cursor2.next;
        cursor2.next=cursor1;
        if(count==0){
            cursor1.next=null;
            count++;
        }
        cursor1=cursor2;
        cursor2=tmp;
    }
    cursor2.next=cursor1;
    root.next=cursor2;
}

测试代码:

    Node结点类:
    public class Node {
        public Node next;
        public int data;
        public Node(){
            next=null;
        }
        public Node(int data){
            this.data=data;
            this.next=null;
        }
    }
链表实现:
public class LinkedList {
    private int size;
    private Node tail;
    private Node root;

    public LinkedList(){
        this.size=0;
        tail=root=new Node();
    }

    public void append(int data){
        tail=tail.next=new Node(data);
        size++;
        return ;
    }

    public void insert(int data,int index){
        if(index<0 || index >size-1){
            System.out.println("index错误");
            return ;
        }
        Node cursor=root;
        for(int i=0;i<index;i++){
            cursor=cursor.next;
        }
        Node tmp=new Node(data);
        tmp.next = cursor.next;
        cursor.next=tmp;
        size++;
    }

    public void traverse(){
        Node cursor=root.next;
        while(cursor!=null){
            System.out.print(cursor.data+" ");
            cursor=cursor.next;
        }
        System.out.println();
    }

    public void remove(int index){
        if(index<0 || index >size-1){
            System.out.println("index错误");
            return ;
        }
        Node cursor=root;
        for(int i=0;i<index;i++){
            cursor=cursor.next;
        }
        cursor.next=cursor.next.next;
        size--;
    }

    public void reverse(){
        if(size==1) return ;
        int count=0;
        Node cursor1=root.next;
        Node cursor2=cursor1.next;
        while(cursor2.next!=null){
            Node tmp=cursor2.next;
            cursor2.next=cursor1;
            if(count==0){
                cursor1.next=null;
                count++;
            }
            cursor1=cursor2;
            cursor2=tmp;
        }
        cursor2.next=cursor1;
        root.next=cursor2;
    }
}
    测试代码:
        public class Main {
        public static void main(String[] args){
            LinkedList ll=new LinkedList();
            for(int i=0;i<10;i++){
                ll.append(i);      //给链表添加元素
            }
            ll.traverse();  // 遍历输出链表内容
            ll.reverse();  //链表反转
            ll.traverse();
        }
    }

image_1cm2miq9d13uu1vbq1d3d1o7v1nt27h.png-12.4kB

posted @ 2018-08-29 19:39  顾杰伟  阅读(136)  评论(0编辑  收藏  举报