zoukankan      html  css  js  c++  java
  • 单链表的反转

    单链表的反转


    单链表概念引入

    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

  • 相关阅读:
    关于用网线连开发板和电脑网卡问题
    信号量同步编程
    信号量互斥编程
    信号通讯
    有名管道通讯
    dell 燃 7000 系列 7460/7560 禁用触控板 触摸板
    关于错误node_modules/@types/jasmine/index.d.ts(39,52): error TS1005: '=' expected.
    环境配置,nodejs,cnpm,git,webstorm,powershell,
    gitflow工作流
    <问题汇总>ionic2开发app
  • 原文地址:https://www.cnblogs.com/gujiewei/p/9670567.html
Copyright © 2011-2022 走看看