1. 线性表
具有相同特征数据元素的一个有限序列, 其中所包含元素的个数称为线性表的长度。
线性表的分类:
2. 数组
2.1 概念
数组是线性表最基本的结构, 由一组相同类型的元素组成, 这些元素在内存中按照一定顺序连续存储。每个数组元素都有唯一索引, 通过索引
可以快速访问数组中的元素, 索引从0开始。
2.2 数组存储元素的特征
- 连续存储: 数组元素在内存中连续存储, 相邻元素之间没有间隔。
- 相同类型: 具有相同的数据类型和大小。
- 定长性: 数组在创建时需要指定长度, 一旦创建后, 其长度是固定不变的。
- 顺序访问: 元素按照索引的顺序依次存储, 通过索引从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--];
}