• 考研中线性表相关代码题


    考研中线性表相关代码题

    1、顺序表的逆置问题

    image-20221016164232431

    SmartSelect_20221016_171440_Samsung Notes
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JWuASA21-1666151784325)(C:\Users\索半斤\Desktop\研究生\blog\images\SmartSelect_20221016_171902_Samsung Notes.jpg)]

    image-20221016172131209

    image-20221016175336508

    image-20221016175358027

    上面的算法基于一种比较朴素的思考方式,假如说原序列是1、2、3、4、5、6,那么我们循环左移2位以后就是3、4、5、6、1、2,那么它其实就相当于是将前n位按原顺序移动到数组后面,同时将后面的元素按原顺序移动到前面。那么我们只需要借助一个辅助数组就可以完成,只是空间复杂度会比较高。

    image-20221016175914902

    2、使用双指针移动元素

    将数组中所有的负数移动到前面

    这种题实际上也是一类题,我们可以通过双指针的方法进行元素置换,比如说,1、2、3、4、5、-1、-2,那我们可以设置一个指向开头的指针left,然后设置一个只想末尾的指针right。然后同时判断left和right的元素值,如果left值大于0,而right的值小于0,那么我们交换两者的位置同时right–,left++;如果right值大于0而left值小于0则直接right–,left++;如果right值小于0而left值也小于0,则left++,right不变,如果right值大于0而left也大于0,则right–,left不变。

    public static void change(int[] array){
        int left = 0;
        int right = array.length-1;
        while(left<right){
            int n1 = array[left];
            int n2 = array[right];
            if(n1 > 0 && n2 > 0 ){
                left++;
                right--;
            }else if(n1>0 && n2 <0){
                array[left] = n2;
                array[right] = n1;
            }else if(n1<0 && n2<0){
                left++;
            }else if(n1<0&&n2>0){
                right--;
            }
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3、顺序表的插入算法考察

    在这里插入图片描述

    public static void insertElem(int[] array,int m,int n){
        //遍历后n个元素,以方便将后n个元素插入到前面
        for (int i = m; i < m+n; i++) {
            //将当前位置元素存入临时变量
            int temp = array[i];
            int j;
            //从当前位置元素的前一个元素开始向前遍历,查找插入位置,也就是当找到比当前元素小的元素时,就插入到这个找到的元素后面
            for (j = i-1; j >=0 && temp
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    4、考察链表相关的插入、删除算法

    在这里插入图片描述

    public static void lickNode(Link l1,Link l2){
        Link p = l1.next;
        Link q = l2.next;
        //设置前一个结点,默认指向l1的头节点,这个节点的作用:因为我们遍历链表时只能遍历到当前节点,所以需要设置指向前一个节点的节点
        Link pre = l1;
        //p和q在遍历过程中都不能为null
        while(p != null && q != null){
            if (p.value < q.value){
                //如果p节点的值小于q节点的值,那么将p赋值给前置节点,然后p节点向后移动
                pre = p;
                p = p.next;
            } else if (p.value > q.value) {
                //如果p节点的值大于q节点的值,那么直接将q节点后移
                q = q.next;
            } else{
                //如果相等,则需要将p中当前的节点删除掉
                pre.next = p.next;
                p = p.next;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    image-20221018110503284

    方法一 建立一个新链表,通过头插法将原链表中的元素插入新链表中,那么倒数第k个也就成了在新链表中查找正数第k个

    public static int findNode(Link link,int k){
        Link newLink = new Link();
        Link head = link.next;
        while(head != null){
            Link temp = newLink.next;
            newLink.next = new Link();
            newLink.next.value = head.value;
            newLink.next.next = temp;
            head = head.next;
        }
        for (int i = 0; i < k && newLink != null; i++) {
            head = newLink.next;
            newLink = newLink.next;
        }
        if (head != null){
            System.out.println(head.value);
            return 1;
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    方法二 我们发现,如果要找倒数第k个,那么我们需要从头节点向后移动n-k+1次(n为除头节点外的节点总数),那么我们可以先遍历一遍链表得到节点总数,然后我们可以根据公式在正向遍历链表查找想要的结果。

    public static int findNode(Link link,int k){
        Link head = link.next;
        int sum = 0;
        while(head != null){
            sum++;
            head = head.next;
        }
        head = link;
        for (int i = 0;i<sum-k+1 && head != null;i++){
            head = head.next;
        }
        if (head != null){
            System.out.println(head.value);
            return 1;
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    方法三 我们可以设置两个指针,初始化时两个指针first、last都指向头节点,随后设置一个变量step,我们判断步长是否为k,如果不为k,那么就不断向后移动last,如果为k,那么我们向后移动first,如果last已经为空,则遍历结束。

    public static int findNode(Link link,int k){
        Link first = link;
        Link last = link;
        int step = 0;
        while(last!= null){
            //一开始step为0,所以在step==k之前一直是last向后移动,随后last和first同时向后并保持step距离
            if (step == k){
                first = first.next;
                step = step-1;
            }else{
                last = last.next;
                step++;
            }
        }
        if (first != null){
            System.out.println(first.value);
            return 1;
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    5、408真题中的顺序表考题

    image-20221018155316777

    方法一 双层暴力循环

    public static void findMainElem(int[] arrays){
        int n = arrays.length;
        for (int i = 0;i<n;i++){
            int m = 1;
            for (int j = i+1; j < n; j++) {
                if (arrays[i] == arrays[j])m++;
            }
            if (m > n/2){
                System.out.println(arrays[i]);
                return;
            }
        }
        System.out.println(-1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    方法二

    image-20221018165723184

    public static void findMainElem02(int[] arrays){
        int c = 0;
        int sum = 0;
        int n = arrays.length;
        for (int i = 0; i < n; i++) {
            if (sum == 0){
                c = arrays[i];
                sum++;
            }else{
                if (c == arrays[i])sum++;
                else sum--;
            }
        }
        sum = 0;
        for (int i = 0; i < n; i++) {
            if (arrays[i] == c)sum++;
        }
        if (sum > n/2){
            System.out.println(c);
        }else{
            System.out.println(-1);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    SA实战 ·《SpringCloud Alibaba实战》第11章-服务容错加餐:Sentinel核心技术与配置规则(最全使用教程)
    代码随想录算法训练营Day60 | 84. 柱状图中最大的矩形
    Springboot笔记-有header的post请求、get请求
    Spring面试题(2022)
    SAP 报表COOIS增强(BADI : WORKORDER_INFOSYSTEM / Method: TABLES_MODIFY_LAY )<转载>
    用于数据分析和数据科学的SQL教程
    ILRuntime1.安装
    Java skill - 自定义feign调用日志打印
    学生HTML网页作业:基于HTML+CSS+JavaScript画家企业8页
    Java面试常见问题总结
  • 原文地址:https://blog.csdn.net/qq_43437555/article/details/127405193