两个非递减顺序表合并成一个非递减顺序表

两个非递减顺序表合并成一个非递减顺序表

  • 引入

以下这个例题的描述是关于合并两个有序的数组,然后合并之后同样也是一个非递减的顺序排列

但是我名这里讲的不是顺序表,而是封装成一个顺序表,但是我们这里的顺序表其实底层同样是一个数组,所以解题的思路完全相同,我们接下来要讲的就是“两个非递减顺序表合成的一个非递减的顺序表”。


合并两个有序数组

给你两个按非递减顺序排列的整数数组 nums 1 和 nums 2,另有两个整数 m 和 n ,分别表示 nums 1 和 nums 2 中的元素数目。


请你合并 nums 2 到 nums 1 中,使合并后的数组同样按非递减顺序排列。


注意:最终,合并后数组不应由函数返回,而是存储在数组 nums 1 中。为了应对这种情况,nums 1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。Nums 2 的长度为 n 。

  • 我们是合并两个顺序表,只是多了一个封装顺序表的步骤,但是该题目的解法思路是大同小异的。

❤️理清思路

  • 非递减顺序表

    非递减就是 “”,而顺序表就是线性表的一种,其逻辑结构是顺序结构,同时其物理结构也和逻辑结构相同的结构,在计算机中存储的物理结构也是连续存储的。

  • 题目要求

    将两个 “非递减顺序表” 合成一个非递减的顺序表,那么我们在实现这个方法的时候需要传两个 “非递减顺序表”作为参数,然后我们就在方法中对这两个顺序表进行操作。并且最后合成的顺序表同样非递减的顺序表,那么我们在实现方法的时候就必须保证顺序表的顺序一致

  • 思路

    自定义一个"顺序表"数据结构,然后定义一个方法 merge (),这个方法要求是传进去两个“非递减的顺序表对象” 参数,分别是 list 1 和 list 2;然后我们在方法中重新 new 一个“新的非递减的顺序表对象”newList,然后定义三个指针分别指向这三个顺序表下标为 0 的位置,利用“穿针引线法”,完成合并工作。

  • 穿针引线法

    我在这里将这种方式描述为 "穿针引线法"是因为真的很形象,但是其实如果是在链表中这样称呼,似乎更加合适。

    我们分别让 i 和 j 永远指向即将进行比较大小的数据元素,然后让 k 在新顺序表中永远都指向“索引等于顺序表有效长度“ 的地方,然后等待 i 和 j 比较的结果的数据元素的插入,直到任意一个顺序表遍历完,
    如果同时遍历完, 那么合并的工作做完了;如果其中一个顺序表遍历玩,而另外一个没有遍历完,那么就把更长的顺序表直接加到 newList 顺序表中。
    综上所述,就完成了两个非递减顺序表的合并工作。


🚀代码实现

package TextReport;  
  
import java.util.Arrays;  
  
public class MyArrayList {  
    //    存放数据的数组  
    public int[] elem;  
    //    记录数组的有效长度  
    public int usedSize;  
    //    常量,用来给数组初始化容量  
    public static final int DEFAULT_CAPACITY = 5;  
  
    //    构造方法  
    public MyArrayList() {  
        this.elem = new int[DEFAULT_CAPACITY];  
    }  
  
    public MyArrayList(int defaultSize) {  
        this.elem = new int[defaultSize];  
    }  
  
    //    打印顺序表的方法(顺序表中有几个有效元素就打印几个有效元素)  
    public void display() {  
        for (int i = 0; i < usedSize; i++) {  
            System.out.print(this.elem[i] + " ");  
        }  
        System.out.println();  
    }  
  
    //    输入(新增加元素,默认在顺序表的最后一个元素的下一个位置上新增)  
    public void add(int data) {  
        try {  
            if (isFull()) {  
                elem = Arrays.copyOf(elem, 2 * elem.length);  
            }  
        } catch (NegativeArraySizeException e) {  
            e.printStackTrace();  
        }  
        Elem[usedSize++] = data;  
    }  
  
    //    在指定位置索引为 pos 新增元素  
    Public void addPos (int data, int pos) {  
        //先判断下标是否合法  
        Try {  
            CheckedAddPos (pos);  
            If (isFull ()) {  
                Elem = Arrays.CopyOf (elem, 2 * elem. Length);  
            }  
            For (int i = usedSize - 1; i > pos; i--) {  
                Elem[i + 1] = elem[i];  
            }  
            Elem[pos] = data;  
            UsedSize++;  
        } catch (PosIndexIllegalException e) {  
            e.getMessage ();  
        }  
  
    }  
  
    //判断顺序表中是否包含某个元素  
    Public boolean contains (int data) {  
        For (int i = 0; i < usedSize; i++) {  
            If (data == elem[i]) {  
                Return true;  
            }  
        }  
        Return false;  
    }  
  
    //返回某个元素的在容器中的索引  
    Public int indexOf (int find) {  
        For (int i = 0; i < usedSize; i++) {  
            If (find == elem[i]) {  
                Return i;  
            }  
        }  
        Return -1;  
    }  
  
  
    //获取指定下标 pos 的值  
    Public int getPos (int pos) {  
        Int retVal = -1;  
        //检查 pos 是否合法  
        Try {  
            CheckGetPos (pos);  
            RetVal = elem[pos];  
            ;  
        } catch (PosIndexIllegalException e) {  
            e.getMessage ();  
        }  
        Return retVal;  
    }  
  
    //      删除第一次出现关键字 key 的方法  
    Public void remove (int key) {  
        //先获取第一次出现 key 元素的下标  
        Int index = indexOf (key);  
        If (index == -1) {  
            System.Out.Println ("没有找到你要删除的数据!");  
            Return;  
        }  
        For (int i = index; i < usedSize - 1; i++) {  
            Elem[i] = elem[i + 1];  
        }  
        UsedSize--;  
    }  
  
    /**  
     * removeAll 方法删除整个顺序表  
     */  
    Public void removeAll () {  
        Elem = new int[5];  
        UsedSize = 0;  
    }  
  
    //    判满方法  
    Private boolean isFull () {  
        Return usedSize == elem. Length;  
    }  
  
    //    判断顺序表的下标是否合法  
    Private void checkedAddPos (int pos) {  
        if (pos < 0 || pos > usedSize) {  
            Throw new PosIndexIllegalException ();  
        }  
    }  
  
    //   判断下标 pos 是否合法  
    Private boolean checkGetPos (int pos) {  
        if (pos < 0 || pos >= usedSize) {  
            Return false;  
        }  
        Return true;  
    }  
  
    /**  
     * 获取顺序表的个数  
     *  
     * @return 返回数组的大小  
     */  
    Public int size () {  
        Return usedSize;  
    }  
  
  
}  
  
  
Class PosIndexIllegalException extends RuntimeException {  
    Public PosIndexIllegalException () {  
  
    }  
  
    Public PosIndexIllegalException (String msg) {  
        Super (msg);  
    }  
}

🍔测试程序

我们是在外部的程序 MyArrayListTest 中进行的测试,先准备两个顺序表,然后调用 merge 方法,并把两个参数传进去,然后会返回一个顺序表,我们再继续调用我们封装的 MyArrayList 类当中的 display 方法。

Package TextReport;  
  
Public class MyArrayListTest {  
    Public static void main (String[] args) {  
        //准备两个顺序表(非递减的顺序表)  
  
        MyArrayList myArrayList 1 = new MyArrayList ();  
        MyArrayList 1.Add (1);  
        MyArrayList 1.Add (5);  
        MyArrayList 1.Add (10);  
        MyArrayList 1.Add (13);  
  
        MyArrayList 1.Display ();  
        ;  
  
        MyArrayList myArrayList 2 = new MyArrayList ();  
  
        MyArrayList 2.Add (6);  
        MyArrayList 2.Add (11);  
        MyArrayList 2.Add (12);  
        MyArrayList 2.Add (33);  
        MyArrayList 2.Add (44);  
        MyArrayList 2.Add (47);  
        MyArrayList 2.Add (52);  
        MyArrayList 2.Add (66);  
  
        MyArrayList 2.Display ();  
        ;  
  
  
        //调用 merge 方法  
  
        MyArrayList mergeArrayList = merge (myArrayList 1, myArrayList 2);  
  
        //调用 display 方法  
        MergeArrayList.Display ();  
  
    }  
  
    /**  
     * 合并两个升序的非递减顺序表,并返回新的合成的顺序表  
     *  
     * @param list 1 按值非递减顺序表一  
     * @param list 2 按值非递减顺序表二  
     * @return 返回一个新的合并了的链表  
     */  
    Public static MyArrayList merge (MyArrayList list 1, MyArrayList list 2) {  
        MyArrayList newList = new MyArrayList (50);  
        Int i = 0, j = 0;  
        While (i < list 1.Size () && j < list 2.Size ()) {  
            If (list 1. Elem[i] < list 2. Elem[j]) {  
                NewList. Elem[newList. UsedSize] = list 1. Elem[i];  
                I++;  
                NewList. UsedSize++;  
            } else {  
                NewList. Elem[newList. UsedSize] = list 2. Elem[j];  
                J++;  
                NewList. UsedSize++;  
            }  
        }  
        While (i < list 1.Size ()) {  
            NewList. Elem[newList. UsedSize] = list 1. Elem[i];  
            I++;  
            NewList. UsedSize++;  
        }  
        While (j < list 2.Size ()) {  
            NewList. Elem[newList. UsedSize] = list 2. Elem[j];  
            NewList. UsedSize++;  
            J++;  
        }  
        Return newList;  
    }  
}


🥰测试结果

在这里插入图片描述


💗图文并茂

该图片是合并结束之后的图示,可以形象的看清楚 i ,j,k 这三个“指针是如何“行走的”。
注意:k 下标其实是 usedSize,是顺序表中的用来表示顺序表的有效长度。

在这里插入图片描述


🎊视频演示

这个视频简单的演示了我当前举的这个例子是如何进行合并的过程,时常两分钟,希望可以看完,这样可以更好的理解 “如何合并两个非递减的顺序表”。

两个非递减顺序表合并视频演示


点赞+收藏+关注💕
请添加图片描述

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值