一、数据结构基本概念1、数据:是所有能输入计算机中并能被计算机程序处理的符号的总称。 数据元素:是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。
数据项:是组成数据元素的、有独立含义的、不可分隔的最小单位。
数据对象:是性质相同的数据元素的集合,是数据的一个子集。
一个数据元素由多个数据项组成。例如学生基本信息表的姓名、学号、性别、成绩等就是数据项,而该学生信息表相当于数据元素。
1、数组
数组是可以再内存中连续存储多个元素的结构,在内存中的分配也是连续的,数组中的元素通过数组下标进行访问,数组下标从0开始。例如下面这段代码就是将数组的第一个元素赋值为 1。
int[] data = new int[100];data[0] = 1;
1
2
优点:
1、按照索引查询元素速度快
2、按照索引遍历数组方便
缺点:
1、数组的大小固定后就无法扩容了
2、数组只能存储一种类型的数据
3、添加,删除的操作慢,因为要移动其他的元素。
适用场景:
频繁查询,对存储空间要求不大,很少增加和删除的情况。
例题 P3156 【深基15.例1】询问学号
AC代码
#include<iostream>
using namespace std;
long long n, m , a[2000050] = { 0 };
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
while (m--) {
int i;
cin >> i;
cout << a[i] << endl;
}
return 0;
}
2、栈
栈是一种特殊的线性表,仅能在线性表的一端操作,栈顶允许操作,栈底不允许操作。 栈的特点是:先进后出,或者说是后进先出,从栈顶放入元素的操作叫入栈,取出元素叫出栈。
栈的结构就像一个集装箱,越先放进去的东西越晚才能拿出来,所以,栈常应用于实现递归功能方面的场景,例如斐波那契数列。
例题 P1449 后缀表达式
AC代码
#include<iostream>
#include<stack>
using namespace std;
stack<int>q;
string c;
int main()
{
cin >> c;
int a = 0, b = 0;
int i, j;
for (int k = 0; k < c.length(); k++)
{
if (c[k] == '@') break;
else if (c[k] == '.') {
q.push(a);
b = 0, a = 0;
}
else if (c[k] <= '9' && c[k] >= '0') {
a = b * 10 + c[k] - '0';
b = a;
}
else {
if (c[k] == '-') i = q.top(), q.pop(), j = q.top(), q.pop(), q.push(j - i);
if (c[k] == '+') i = q.top(), q.pop(), j = q.top(), q.pop(), q.push(j + i);
if (c[k] == '*') i = q.top(), q.pop(), j = q.top(), q.pop(), q.push(j * i);
if (c[k] == '/') i = q.top(), q.pop(), j = q.top(), q.pop(), q.push(j / i);
}
}
cout << q.top();
return 0;
}
3、队列
队列与栈一样,也是一种线性表,不同的是,队列可以在一端添加元素,在另一端取出元素,也就是:先进先出。从一端放入元素的操作称为入队,取出元素为出队。
队列的常见基本操作
使用场景:因为队列先进先出的特点,在多线程阻塞队列管理中非常适用。
例题 P1996 约瑟夫问题
AC代码
#include<iostream>
#include<queue>
using namespace std;
queue <int> q;
int main()
{
int n, k, s = 0;
cin >> n >> k;
for (int i = 1; i <= n; i++) q.push(i);
while (!q.empty()) {
for (int i = 1; i < k; i++) {
q.push(q.front());
q.pop();
}
printf("%d ", q.front());
q.pop();
}
return 0;
}
4、链表
链表是物理存储单元上非连续的、非顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,每个元素包含两个结点,一个是存储元素的数据域 (内存空间),另一个是指向下一个结点地址的指针域。根据指针的指向,链表能形成不同的结构,例如单链表,双向链表,循环链表等。
链表的优点:
链表是很常用的一种数据结构,不需要初始化容量,可以任意加减元素;
添加或者删除元素时只需要改变前后两个元素结点的指针域指向地址即可,所以添加,删除很快;
缺点:
因为含有大量的指针域,占用空间较大;
查找元素需要遍历链表来查找,非常耗时。
适用场景:
数据量较小,需要频繁增加,删除操作的场景
链表一般分为:
单向链表
双向链表
环形链表
关于链表具体操作可以借鉴c语言链表详解(超详细)