【25届秋招备战C++】数据结构篇-数组

一、数组定义

一种线性表数据结构。数组在连续内存空间中存储相同类型的元素。顺序结构存储

1.数组的下标是从0开始的
2.数组内存空间是连续的
3.数组不能删除,只能覆盖
4.数组中的数据元素可随机访问
注意:区分元素与索引;区分访问与搜索


PS:数组和指针都可以像标准库的vector一样顺序地遍历一组数据,然而他们与vecto相比却能更直接地接触到计算机的内存,因此在高效的同时也会有更大的风险。所以在一般情况下,推荐使用vector。 vector 的push_back()操作可以无限的添加元素,因此vector 是动态的,而数组是一种完全静态的数据结构,在初始化的时候要给数组指定大小,并且不能修改。

vector与array:vector的底层实现是array,严格来讲vector是容器,不是数组。

二、算法复杂度

访问(Access)-O(1)
搜索(Search)-O(N)
插入(Insert)-O(N)
删除(Delete)-O(N)

三、常用操作

创建数组

1.array

一维:数据类型 数据名[x];
二维:数据类型 数组名[x][y];

初始化:一维数组的初始化,需要给出用逗号隔开的从第一个元素开始的若干个元素的初值,并用大括号括住。后面未被赋初值的元素默认为0
在多数情况下,C++将数组名解释为数组第一个元素的地址 二维数组名是地址的地址,必须两次取值才可以取出数组中存储的数据
2.vector

vector<int>nums;//创建整型一维数组 
vector<int>nums(n);//指定长度为n 
vector<int>nums(5,3);//创建[3 3 3 3 3] 
vector<vector<int>>nums;//创建数组 
vector<vector<int>>nums(3);//创建三行的数组 
vector<vector<int>>nums(3,vector<int>(5,0)); //创建三行五列的数组,初始值为0

注意:vector 在创建的时候需要元素类型和名称两个信息,大小可以在初始化的时候指定,也可以不指定。 由于数组是静态的一定要为其指定大小,称作数组的维度。

访问/修改元素

访问元素思路-下标访问

1.判断是否在合法区间
2.由给定下标得到元素的值

修改元素思路-访问后直接赋值

遍历数组

1.array-for循环遍历

for (int i = 0; i < a.size(); i++) {
		cin >> a[i];
	}

 2.vector

//第一种遍历方式,下标
	cout << "第一种遍历方式,下标访问" << endl;
	for (int i = 0; i<m_testPoint.size(); ++i)
	{
 
		cout << m_testPoint[i].x << "	" << m_testPoint[i].y << endl;
	}
 
	//第二种遍历方式,迭代器
	cout << "第二种遍历方式,迭代器访问" << endl;
	for (vector<Point>::iterator iter = m_testPoint.begin(); iter != m_testPoint.end(); iter++)
	{
		cout << (*iter).x << "	" << (*iter).y << endl;
	}
 
	//第三种遍历方式,auto关键字
	cout << "C++11,第三种遍历方式,auto关键字" << endl;
	for (auto iter = m_testPoint.begin(); iter != m_testPoint.end(); iter++)
	{
		cout << (*iter).x << "	" << (*iter).y << endl;
	}
 
	//第四种遍历方式,auto关键字的另一种方式
	cout << "C++11,第四种遍历方式,auto关键字" << endl;
	for (auto i : m_testPoint)
	{
		cout << i.x << "	" << i.y << endl;
	}

查找元素

查找元素思路-循环

1.建立基于下标的循环,比较val与nums[i]
2.找到元素返回元素下标
3.遍历完找不到则返回特殊值

for i in range(len(nums)):
        if nums[i] == val:
        return i

 添加/插入元素

1.array
定义时就已经在栈上分配空间大小,运行时不改变,不能直接添加/插入,但可以赋值。

nums[0]=1;

数组增加元素的思路:

  1. 建一个新的数组,数组长度为原数组的长度加一。
  2. 将需要增加的元素值赋给数组的最后一个元素。
  3. 将新的数组赋给原来的数组
//参考代码:在一个数组的第x个位置插入一个新的数y
#include <iostream>
using namespace std;
 
int main() {
	int n, x, y, a[11];
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	cin >> x;
	cin >> y;
	x--;
	for (int i = n - 1; i  >= x; i--) {
		a[i + 1] = a[i];
	}
	a[x] = y;
	n++;
	for (int i = 0; i <= n - 1; i++) {
		cout << a[i] << " ";
	}
}

2.vector

nums.push_back(a);//在数组末尾添加a 
num[i]=2;//直接赋值 
//整体赋值:3种方法
//1.等号直接赋值
vector<int>nums1; 
nums1=nums;
//2.assign函数赋值
nums1.assign(nums.begin().nums.end());//也可以用迭代器
//3.for循环赋值
vector<int> :: iterator iter;
for(iter=nums.begin();iter!=nums.end();iter ++){
    nums1.push_back(*iter);
}

assign函数原型

void assign(const_iterator first,const_iterator last);
void assign(size_type n,const T& x = T());
/*
功能:
第一个相当于拷贝函数,把first到last的值赋值给调用者,注意区间的闭合,即:将区间 [first,last) 的元素赋值到当前的 vector 容器中;
第二个是把n个x赋值给调用者,即:赋 n 个值为 x 的元素到 vector 容器中,并且清除掉 vector 容器中以前的内容。
*/

注意:vector容器是不能够通过下标操作添加元素的,只有已经存在的元素才能用下标索引,否则会报错。参见【C++ Error】runtime error -vector的初始化问题-CSDN博客

删除元素

1.array 定义时就已经在栈上分配空间大小,运行时不改变,不能直接删除,但可以覆盖。

数组删除的思路

  1. 创建一个新数组,数组长度为原来数组的长度减一
  2. 定义需要删除的元素下标
  3. 将删除下标之前的元素赋给新数组的下标值,删除下标之后的元素赋给新数组下标值-1
//代码待补充

2.vector

//删除最后一个元素
    nums.resize(nums.size()-i);//减少i个元素
    nums.pop_back();//括号里面不用加东西,删除最后一个元素
//删除某段元素或某位上的元素
#include <algorithm>		// [注意] :remove位于algorithm函数库中

    a.erase(remove(a.begin(),a.end(),2),a.end());//erase里面放迭代器
//基于条件删除元素-循环查找元素后删除,同样erase

remove函数本质上其实并没有完成元素的完全删除工作,因为容器的大小都没有改变,它只是将所有被删除的元素用下一个不被删除的元素进行覆盖,同时返回一个迭代器,在该迭代器之前的所有元素,保留原容器的顺序,并且不存在被删除的元素,也就是你想要的容器内容,而该迭代器到容器的末尾则不变,也就是说,原容器的大小没有发生变化,被删除的元素也确实没有了,但容器末尾的一些元素(个数等于被删除元素个数)又会多出来一份,这是我们不愿意看到的,因此需要借助上面提到的erase函数。所以说remove需要和erase搭配使用才能实现完整的删除功能。

注意:vector容器是不能够通过下标操作添加元素的,只有已经存在的元素才能用下标索引,否则会报错。参见【C++ Error】runtime error -vector的初始化问题-CSDN博客

数组的长度

//一维
    nums.size();//数组的长度
    cout << nums[0] << endl;//输出第一个元素
    cout << nums[nums.size()-1] << endl;//输出最后一个元素
    nums.resize(m);//长度改为m
//二维
    m=A.size();//row
    n=A[0].size();//column

是否为空,清空

1.array

int nums[] = {1,2,3};
//先计算数组长度
nums_length = sizeof(nums)/sizeof(nums[0]);
//再判断是否为0

2.vector

    nums.empty(); //判断是否空
    nums.clear(); //清空
    vector<int>().swap(nums); //清空,将容器与空容器交换从而删除容器数据并收回内存
    nums.shrink_to_fit();	//  将vector 容器的容量缩减至和实际存储元素的个数相等

排序、翻转、合并

#include<algothrim>
    
    sort(nums.begin(),nums.end());//从小到大排序
    sort(nums.begin(),nums.begin()+3);//排序前面三个数
 
    reverse(nums.begin(),nums.end());//翻转
    
    //将nums1和nums2合并
    vector<int>nums1(m),nums2(n);
    vector<int>nums;
    nums.resize(m+n);
    merge(nums1.begin(),nums1.end(),nums2.begin(),nums2.end(),nums);

四、参考

vector容器v1、v2之间相互赋值的三种方法及易错点详解_两个vector赋值-CSDN博客

01. 数组基础知识 | 算法通关手册(LeetCode) (itcharge.cn)

代码随想录 (programmercarl.com)

C++ Vector遍历的几种方式_遍历vector-CSDN博客

C++数组元素的插入_c++数组添加元素-CSDN博客

【C++】STL中vector的assign()函数用法_vector assign-CSDN博客

C++ std::vector删除元素的几种方式及区别_stdvector删除元素-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值