数组:
可以说是最简单的一种数据结构,它占据一块连续的内存并按照顺序存储数据.创建数组时:我们需要首先制定数组的容量的大小,然后根据大小分配内存.即使我们只在数组中存储一个数字,也需要为所有的数据预先分配内
存.因此数组的空间效率不是很好,经常会有空闲的区域没有得到充分的利用.....
由于数组中的内存都是连续的,于是我们可以根据下标在O(1)时间(直接检索下标获得存储的数据)内读/
写任何元素,因此时间效率是很高的(已经是简单初步的哈希了).我们可以根据数组时间效率高的优点,用数组来
实现简单的哈希表:把数组的下标设为哈希表的键值(Key),而把数组中的每一个数字设为哈希(Value)
,,这样每一个下标及数组中该下标对应的数字就组成了一个键值-值的配对.
然而,为了解决数组空间效率不高的问题,人们又设计了多种动态数组,比如C++的STL中的vector.
为了避免浪费,我们先为数组开辟较小的空间,然后忘数组中添加数据.当数据的数目超过数组的容量时,我们在重
新分配一块更大的空间(STL的vector每次扩充容量时,新的容量都是前一次的两倍),把之前的数据复制
到新的数组中,再把之前的内存释放调,这样就能减少内存的浪费.当我们不可忽略的是:
每一次扩充数组容量时都有大量的额外操作,这对时间性能有负面影响,因此使用动态数组时要尽量减少改变数 组容量大小的次数.
在C/C++中,数组和指针是相互关联又有区别的两个概念.当我们声明一个数组时,其数组的名字也是一个指针
,该指针指向数组的第一个元素.我们可以用一个指针来访问一个数组.
还要注意的是:C/C++没有记录数组的大小,因此用指针访问数组中的元素时,我们要确保没有超出数组的边界.我们来看看代码:
#include <stdio.h>
long int Getsize(int data[])
{
return sizeof(data);
}
int main()
{
int data[] = {1,2,3};
int *data1 = data;
printf("%ld\n", sizeof(data));
printf("%ld\n", Getsize(data));
printf("%ld\n", sizeof(data1));
return 0;
}
运行结果:
data是一个数组,sizeof(data)是求数组的大小.这个数组包含3个整数,每个整数占用4个字节,因此总共12个字节.
data1声明为指针,尽管它指向了数组data的第一个数字,但是本质仍然是一个指针.在64位系统上,对
任意指针求sizeof,结果都是8.
在C/C++中,当数组作为函数的参数进行传递时,数组就自动退化为同类型的指针.所以结果是4.
我们在linux终端下敲入这个命令:出现32(那么就是32位系统),出现64(那么就是64位系统)
大家看运行结果:
面试:二维数组中的查找(剑指offer)
题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成
一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数....
例如下面的二维数组就是每行每列都递增顺序.如果在这个数组中查找数字7,则返回true;如果查找数字5,由于数组中不含有该数字,则返回false.
第一种解法:二维数组的遍历
1,这个题要是按照普通的二维数组遍历来查找的话,也能完成相应的功能,但是也就不能体现二维数组原有有序的
优势了,跟有序就已经没有什嘛关系了,,,如果数组非常大的话,那么将及其浪费时间O(N*N)
我们可以试一下,因为我们首先就要构建一个这样的数组,边构建边比较
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
int row = 0, col = 0, t = 0;
int testNum[100][100];
bool isFound = false;
while(cin >> row >> col >> t)
{
isFound = false;
for(int i = 0; i < row ; ++i)
{
for(int j = 0; j < col; ++j)
{
//输入每个数
cin>>testNum[i][j];
//边输入边验证
if(false == isFound && t == testNum[i][j])
{
//已经找到后就没必要再找了
isFound = true;
}
}
}
if(true == isFound)
{
cout << "Yes" << endl;
}
else
{
cout << "No" << endl;
}
}
return 0;
}
但是:Time Limit Exceed(好大的时间啊,,,,说明测试的时候比较的太多了,当前的这个二维数组太大了)
处理这个问题的时候:根据特性,我们会想着将其画成矩形,然后从数组中选取一个数字,分3中情况来查找
1,当要查找的数字刚好和要查找的数字相等时,就结束查找过程
2,如果选取的数字小于要查找的数字,那么根据排序的规则,要查找的数字应该在当前选取的位置的右边或下边
3,如果选取的数字大于要查找的数字,那么要查找的数字应该在当前选取的位置的上边或者左边
但是,我们的这样处理真的好吗???
如下:
但是,我们要找9,6的时候并不能找到啊!!!!!!
当,我们需要解决一个复杂的问题时,一个很有效的办法就算从一个具体的问题入手,通过分析简单具体的例子,试图寻找普遍的规律.
如果我们从数组的一个角上选取数字来和要查找的数字做比较,情况会不会变得简单了呢???
那么我们选取数组右上角的数字9.由于9大于7,并且9还是第四列的一个个数字(也是最小的)数字,因此7不可能出现在9所在的列.于是我们把这一列剔除掉,之后只需要分析剩下的3列:
在剩下的矩阵中,位于右上角的数字是8.同样8大于7,继续剔除.接下来我们只需要分析剩下的两列即可.
在由剩余的两列组成的数组中,数字2位于数组的右上角.2小于7,那么要查找的只能位于2的下边.于是我们继续剔除行,到了右上角的4,我们继续剔除行,在往下走就到了7,好了,那么我们就找到了....
总结上述查找过程:我们发现如下规律,首先我们选取数组中右上角的数字.如果该数字等于要查找的数字,查找过程结束;如果该数字大于要查找的数字,剔除这个数字所在的列;如果该数字小于要查找的数字,剔除这个数字所在的行.一步一步缩小查找的范围.直到范围为空为止...
// 二维数组matrix
// 每一行都从左到右递增排序
// 每一列都从上到下递增排序
bool Find(int *matrix, int rows, int columns, int number)
{
bool found = false;
if(matrix != NULL && rows > 0 && columns > 0)
{
int row = 0;
int column = columns - 1;
while(row < rows && column >=0)
{
if(matrix[row * columns + column] == number)
{
found = true;
break;
}
else if(matrix[row * columns + column] > number)
--column;
else
++row;
}
}
return found;
}
这样我们的时间复杂度就大大的降低了:O(N)了