zoukankan      html  css  js  c++  java
  • 链表问题-不开辟新空间

    1,将单向链表【逆向翻转】

    方法1:直接使用索引进行,有点类型冒泡排序,但是又不同,时间复杂度O(n^2)。

    0-1-2-3-4

    1-0-2-3-4

    1-2-0-3-4

    1-2-3-0-4

    1-2-3-4-0

    将head转到tail

    再次将新head转到倒数第二个

    方法2:直接使用递归进行,指向与尾部索引更改

    package com.cnblogs.mufasa.demo1;
    
    public class Node {
        public int value;
        public Node next;
        public Node(int value){
            this.value=value;
        }
    
        public void add(int value){
            Node pre=this;
            while (pre.next!=null){
                pre=pre.next;
            }
            pre.next=new Node(value);
        }
    
        public static Node reverseList(Node head){//1,利用Node索引解决问题【完成】
            Node next=null;
            Node pre=null;
            while (head!=null){
                next=head.next;
                head.next = pre;
                pre=head;
                head=next;
            }
            return pre;
        }
        public static Node reverseList2(Node head){//2,利用递归解决问题【完成】
            if (head == null || head.next == null) {
                return head;//节点为空或单节点
            }
            //递归反转子lian链表
            Node newList = reverseList2(head.next);
            //第三张图,原本:1-2-3-4-->2-1-nul 34
            head.next.next = head;
            head.next = null;
            return newList;
        }
    }
    
    class client{
        public static void main(String[] args) {
            Node root=new Node(1);
            for(int i=2;i<10;i++){
                root.add(i);
            }
            Node reRoot=Node.reverseList(root);
            Node reRoot1=Node.reverseList2(root);
    
        }
    }

    2,拓展【部分翻转】【结合第二种方法直接在指定节点进行拆分、合并2019-09-10】

      给定一个单链表的头节点 head,实现一个调整单链表的函数,使得每K个节点之间为一组进行逆序,并且从链表的尾部开始组起,头部剩余节点数量不够一组的不需要逆序。(不能使用队列或者栈作为辅助)

      先来个简单的算法【从头开始每隔3个进行翻转】:【递归调用】

        public Node reverseForwordSingle(Node head,int k){//正序特定长度翻转
            if(head==null){
                return null;
            }else if(head.next==null){
                return head;
            }
            Node pre=null;
            Node next=null;
            int counter=0;
            while (head!=null &&counter<k){
                next=head.next;
                head.next=pre;
                pre=head;
                head=next;
                counter+=1;
            }
            head=pre;
            while (pre.next!=null){
                pre=pre.next;
            }
            pre.next=reverseForwordSingle(next,k);
            return head;
        }

      

      后面的逆序翻转,有使用顺序翻转的方法:

        public Node reverseBackwordSingle(Node head,int k){//逆序特定长度翻转
            if(head==null){
                return null;
            }else if(head.next==null){
                return head;
            }
    
            int counter=1;//对数据进行计数
            Node pre=head;
            while (pre.next!=null){
                pre=pre.next;
                counter+=1;
            }
    
            if(counter%k==0){//刚好整除
                return reverseForwordSingle(head,k);
            }else if(counter%k==1) {//前面需要进行 有1个余数
                pre = head;
            }else {
                pre = head;
                int counter1=1;
                while (counter1<counter%k){
                    counter1+=1;
                    pre=pre.next;
                    if(pre==null){
                        return head;
                    }
                }
            }
    
            pre.next=reverseForwordSingle(pre.next,k);
            return head;
        }
    package com.cnblogs.mufasa.demo2;
    
    public class Node {
        public int value;
        public Node next;
        public Node(int value){
            this.value=value;
        }
    
        public void add(int value){//添加节点
            Node pre=this;
            while (pre.next!=null){
                pre=pre.next;
            }
            pre.next=new Node(value);
        }
    
        public static String traverse(Node root){
            if(root==null){
                return "null";
            }else if(root.next==null){
                return root.value+"-";
            }
            String str=root.value+"-";
            while (root.next!=null){
                root=root.next;
                str+=root.value+"-";
            }
            return str;
        }
    
        public Node reverseForwordSingle(Node head,int k){//正序特定长度翻转
            if(head==null){
                return null;
            }else if(head.next==null){
                return head;
            }
            Node pre=null;
            Node next=null;
            int counter=0;
            while (head!=null &&counter<k){
                next=head.next;
                head.next=pre;
                pre=head;
                head=next;
                counter+=1;
            }
            head=pre;
            while (pre.next!=null){
                pre=pre.next;
            }
            pre.next=reverseForwordSingle(next,k);
            return head;
        }
    
        public Node reverseBackwordSingle(Node head,int k){//逆序特定长度翻转
            if(head==null){
                return null;
            }else if(head.next==null){
                return head;
            }
    
            int counter=1;//对数据进行计数
            Node pre=head;
            while (pre.next!=null){
                pre=pre.next;
                counter+=1;
            }
    
            if(counter%k==0){//刚好整除
                return reverseForwordSingle(head,k);
            }else if(counter%k==1) {//前面需要进行 有1个余数
                pre = head;
            }else {
                pre = head;
                int counter1=1;
                while (counter1<counter%k){
                    counter1+=1;
                    pre=pre.next;
                    if(pre==null){
                        return head;
                    }
                }
            }
    
            pre.next=reverseForwordSingle(pre.next,k);
            return head;
        }
    
    }
    
    class Client{
        public static void main(String[] args) {
            Node root=new Node(1);
            for(int i=2;i<10;i++){
                root.add(i);
            }
            System.out.println(root.traverse(root));
    //        Node reRoot= root.reverseForwordSingle(root,3);
    //        System.out.println(root.traverse(reRoot));
    
            Node reRoot1= root.reverseBackwordSingle(root,5);
            System.out.println(root.traverse(reRoot1));
        }
    }
    /*
    1-2-3-4-5-6-7-8-9-
    1-2-3-4-9-8-7-6-5-
     */
    View Code
  • 相关阅读:
    记录锁
    linux多线程同步pthread_cond_XXX条件变量的理解
    设置创建文件掩码遇到的问题
    函数的可重入和线程安全
    sigemptyset,sigfillset,sigaddset,sigdelset,sigismember,sigprocmask,sigpendmask作用
    嵌入式中断服务函数的一些特点
    linux alarm函数解除read write等函数的阻塞
    孤儿进程,僵死进程
    标准IO的缓冲问题
    《实用技巧》——让你的网站变成响应式的3个简单步骤
  • 原文地址:https://www.cnblogs.com/Mufasa/p/11409826.html
Copyright © 2011-2022 走看看