算法通关村——不简单的数组增删改查

本文详细介绍了数组作为线性表基础结构的概念,包括数组的存储特性、基本操作(如创建、查找、增加和删除元素),以及如何判断单调数组和合并两个已排序数组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 线性表

具有相同特征数据元素的一个有限序列, 其中所包含元素的个数称为线性表的长度。

线性表的分类:

在这里插入图片描述

2. 数组

2.1 概念

数组是线性表最基本的结构, 由一组相同类型的元素组成, 这些元素在内存中按照一定顺序连续存储。每个数组元素都有唯一索引, 通过索引
可以快速访问数组中的元素, 索引从0开始。

在这里插入图片描述

2.2 数组存储元素的特征

  1. 连续存储: 数组元素在内存中连续存储, 相邻元素之间没有间隔。
  2. 相同类型: 具有相同的数据类型和大小。
  3. 定长性: 数组在创建时需要指定长度, 一旦创建后, 其长度是固定不变的。
  4. 顺序访问: 元素按照索引的顺序依次存储, 通过索引从0开始逐个访问。

2.3 数组的基本操作

2.3.1 创建和初始化

// 创建长度为10的整型数组
int[] arr = new int[10];
// 创建并初始化一个包含初始值的整型数组
int[] nums = {1, 2, 3, 4, 5}; 

2.3.2 查找元素

/**
 * @param arr
 * @param size 已经存放的元素容量
 * @param key  待查找的元素
 * @return
 */
public static int findByElement(int[] arr, int size, int key) {
    for (int i = 0; i < size; i++) {
        if (arr[i] == key)
            return i;
    }
    return -1;
}

2.3.3 增加一个元素

将给定的元素插入到有序数组的对应位置中。先找位置, 再将其后元素整体右移, 最后插入到空位置上。

/**
 * @param arr
 * @param size    数组已经存储的元素数量
 * @param element 待插入的元素元素
 * @return
 */
public static int addByElementSequence(int[] arr, int size, int element) {
  if (size >= arr.length) {
    return -1;
  }
  int index = size;
  // 找到新元素的插入位置
  for (int i = 0; i < size; i++) {
    if (element < arr[i]) {
      index = i;
      break;
    }
  }
  // 元素后移
  for (int i = size; i > index; i--) {
    arr[i] = arr[i - 1];
  }
  // 插入数据
  arr[index] = element;
  return index;
}

2.3.4 删除一个元素

遍历数组,如果发现目标元素,则将其删除, 数组的删除就是从目标元素开始,用后续元素依次覆盖前继元素

/**
 * @param arr  数组
 * @param size 数组中的元素个数
 * @param key  要删除的目标值
 */
public static int removeByElement(int[] arr, int size, int key) {
  int index = -1;
  for (int i = 0; i < size; i++) {
    if (arr[i] == key) {
      index = i;
      break;
    }
  }
  if (index != -1) {
    for (int i = index; i < size; i++) {
      arr[i] = arr[i + 1];
    }
    size--;
  }

  return size;
}

3. 单调数组

判断一个给定的数组是否为单调数组。

分析:
如果对于所有 i <= j, arr[i] < arr[j], 那么数组arr是单调递增的。同理, 如果对于所有 i <= j, arr[i] > arr[j], 那么数组arr是单调递减的。

代码实现:

/**
 * 如果是递增的就一定不能出现递减的相邻元素,
 * 如果出现递减的就一定不能出现递增的相邻元素。
 * @param nums
 * @return
 */
public static boolean isMonotonic_2(int[] nums) {
    boolean inc = true, dec = true;
    for (int i = 0; i < nums.length - 1; i++) {
        if (nums[i] > nums[i + 1]) {
            inc = false;
        }
        if (nums[i] < nums[i + 1]) {
            dec = false;
        }
    }
    return inc || dec;
}

4. 数组合并

给你两个按非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序排列。

示例:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:合并 [1,2,3] 和 [2,5,6] 的结果是 [1,2,2,3,5,6]

分析:
因为数组nums1 和 nums2 的元素数量是固定的, 所以排序后最后的位置一定是 nums1 和 nums2中元素都最大的那个, 依次类推, 每次都找到最大的那个从后向前填。

代码实现:

/**
 * 两个数组从后向前逐步合并
 *
 * @param nums1
 * @param nums1_len
 * @param nums2
 * @param nums2_len
 */
public static void merge2(int[] nums1, int nums1_len, int[] nums2, int nums2_len) {
    int i = nums1_len + nums2_len - 1;
    int len1 = nums1_len - 1; int len2 = nums2_len - 1;
    while (len1 >= 0 && len2 >= 0) {
        if (nums1[len1] > nums2[len2]) {
            nums1[i--] = nums1[len1--];
        } else {
            nums1[i--] = nums2[len2--];
        } 
    }
    //假如A或者B数组还有剩余
    while (len1 != -1) nums1[i--] = nums1[len1--];
    while (len2 != -1) nums1[i--] = nums2[len2--];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值