赞
踩
每一种编程语言中,基本都有数组这种数据类型。它不仅仅是一种数据类型,还是一种最基础的数据结构。
数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。
数组只用来存储指定类型的数据,所以存储n个数据的空间复杂度为O(n)。
数组插入数据,特定场景,特殊对待,如下:
数组删除数据,特定场景,特殊对待,如下:
考虑内存连续性:
数组需要保持有序:删除k位置元素后,将后面的元素依次前移一个位置。O(n)
数组不需要保持有序:用最后一个元素覆盖要删除的元素。O(1)
不考虑内存连续:
标记删除法,将要删除的元素标记(没有真正的删除),当数组空间不够时,一次性删除。但会造成内存不连续,如下图:
数组空间:数组所占内存空间,不随插入或删除元素而改变,除非申请空间
数组长度:数组所存储的数据元素个数,随插入或删除元素而改变
以存储整型数据为例
对于数组int a[],其地址为a,第一个数组元素的地址和数组的地址相等,第二个数据元素的地址为a+4,依次类推,每往后移动一个数据元素,地址加4,可见只要知道了数组的首地址,就知道了数组中每一个元素的地址,所以利用数组下标可以实现数组元素的随机访问。
随机访问寻址方法:a[i]_address = base_address + i * data_type_size
其中,base_address 为数组首地址,data_type_size 为每个元素的大小,依数据类型确定。
#include <stdio.h>
int main()
{
int a[] = {0, 1, 2, 3};
printf(" a.address: %p\n", a);
for (int i = 0; i < 4; i++)
{
printf("a[%d].address: %p\n", i, &a[i]);
}
}
打印结果为:
a.address: 0x7ffd46f51c50
a[0].address: 0x7ffd46f51c50
a[1].address: 0x7ffd46f51c54
a[2].address: 0x7ffd46f51c58
a[3].address: 0x7ffd46f51c5c
给定一个含有n个元素的字符数组a,将其原地逆序
// 字符串逆序
void Reverse(char*a, int n)
{
int left =0;
int right = n -1;
while (left < right)
{
char temp = a[left] ;
a[left++] = a[right] ;
a[right--] = temp ;
}
}
给定一个含有n个元素的整型数组a,从中任取m个元素,求所有组合。比如下面的例子
a = 1, 2, 3, 4, 5
m = 3
输出
1 2 3, 1 2 4, 1 2 5, 1 3 4, 1 3 5, 1 4 5
2 3 4, 2 3 5, 2 4 5
3 4 5
// n选m的所有组合 int buffer[100] ; void PrintArray(int *a, int n) { for (int i = 0; i < n; ++i) cout << a[i] << ""; cout << endl ; } bool IsValid(int lastIndex, int value) { for (int i = 0; i < lastIndex; i++) { if (buffer[i] >= value) return false; } return true; } void Select(int t, int n, int m) { if (t == m) PrintArray(buffer, m); else { for (int i = 1; i <= n; i++) { buffer[t] = i; if (IsValid(t, i)) Select(t + 1, n, m); } } }
给定含有n个元素的两个有序(非降序)整型数组a和b。合并两个数组中的元素到整型数组c,要求去除重复元素并保持c有序(非降序)。例子如下
a = 1, 2, 4, 8
b = 1, 3, 5, 8
c = 1, 2, 3, 4, 5, 8
分析
利用合并排序的思想,两个指针i,j和k分别指向数组a和b,然后比较两个指针对应元素的大小,有以下三种情况
a[i] < b[j],则c[k] = a[i]。
a[i] == b[j],则c[k]等于a[i]或b[j]皆可。
a[i] > b[j],则c[k] = b[j]。
重复以上过程,直到i或者j到达数组末尾,然后将剩下的元素直接copy到数组c中即可
// 合并两个有序数组 void Merge(int *a, int *b, int *c, int n) { int i = 0 ; int j = 0 ; int k = 0 ; while (i < n && j < n) { if (a[i] < b[j])// 如果a的元素小,则插入a中元素到c { c[k++] = a[i] ; ++i ; } else if (a[i] == b[j])// 如果a和b元素相等,则插入二者皆可,这里插入a { c[k++] = a[i] ; ++i ; ++j ; } else // a[i] > b[j] // 如果b中元素小,则插入b中元素到c { c[k++] = b[j] ; ++j ; } } if (i == n) // 若a遍历完毕,处理b中剩下的元素 { for (int m = j; m < n; ++m) c[k++] = b[m] ; } else//j == n, 若b遍历完毕,处理a中剩下的元素 { for (int m = i; m < n; ++m) c[k++] = a[m] ; } }
给定含有n个元素的整型数组a,其中包括0元素和非0元素,对数组进行排序,要求:
排序后所有0元素在前,所有非零元素在后,且非零元素排序前后相对位置不变
不能使用额外存储空间
例子如下
输入 0, 3, 0, 2, 1, 0, 0
输出 0, 0, 0, 0, 3, 2, 1
void Arrange(int* a, int n) { int k = n -1 ; for (int i = n -1; i >=0; --i) { if (a[i] !=0) { if (a[k] ==0) { a[k] = a[i] ; a[i] =0 ; } --k ; } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。