数据结构在计算机科学中扮演着至关重要的角色,它是存储和组织数据的基本方式。在软件开发中,了解和熟练掌握各种数据结构是非常重要的,因为选择合适的数据结构可以极大地影响程序的性能和效率。在本文中,我们将讨论一些常见的数据结构,包括链表、队列、栈、堆、并查集、哈希表和树。
链表是一种线性数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表可以是单向的,也可以是双向的。在C++中,我们可以使用指针来实现链表。
#include<iostream>
using namespace std;
const int N=100010;
//head是头节点下标
//e[i]表示节点i的值
//ne[i]表示节点i的next的指针是多少
int head , e[N],ne[N];
//存储用到了哪个点
int idx;
void chu()
{
head=-1;
idx=0;
}
//将x插到头节点
void add_link_head(int x)
{
e[idx]=x;
ne[idx] = head;
head = idx;
idx++;
}
//将x插到k节点的后边
void add_link(int k,int x)
{
e[idx] = x;
ne[idx] = ne[k];
ne[k] = idx;
idx ++;
}
//将下标是k下一个节点删掉
void remove(int k)
{
ne[k]=ne[ne[k]];
}
int main()
{
int m;
cin>>m;
chu();
while(m--)
{
int k,x;
char ch;
cin>>ch;
if(ch=='H')
{
cin>>x;
add_link_head(x);
}
else if(ch=='D')
{
cin>>k;
remove(k-1);
}
else{
cin>>k>>x;
add_link(k-1,x);
}
}
for(int i = head ; i != -1 ;i = ne[i])
{
cout << e[i] <<' ';
}
return 0;
}
队列是一种先进先出(FIFO)的数据结构,可以用于实现广度优先搜索(BFS)等算法。在C++中,我们可以使用STL中的queue来实现队列。
#include<cstdio>
#include<iostream>
#include<cstring>
#include <iterator>
using namespace std;
const int N = 100010;
int q[N],hh,tt = -1;
//插入
void push(int x)
{
q[ ++tt] = x;
}
//弹出
void pop()
{
hh++;
}
//判断队列是否为空
void empty()
{
if(hh<=tt) printf("NO\n");//不为空
else printf("YES\n");
}
int query()
{
return q[hh];
}
int main()
{
int m,x;
scanf("%d",&m);
while(m--)
{
string ch;
cin>>ch;
if(ch=="push")
{
cin>>x;
push(x);
}
else if(ch=="pop")
{
pop();
}
else if(ch=="empty")
{
empty();
}
else
{
printf("%d\n",query());
}
}
}
栈是一种后进先出(LIFO)的数据结构,可以用于实现深度优先搜索(DFS)等算法。在C++中,我们可以使用STL中的stack来实现栈。
#include <iostream>
#include <stack>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
stack <int> stk;
int m;
cin >> m;
while(m --){
int x;
string op;
cin >> op;
if(op =="push"){
cin >> x;
stk.push(x);//入栈
}
else if(op == "query"){
cout << stk.top() << endl;//输出栈顶元素
}
else if(op =="pop"){
stk.pop();//出栈
}
else{
if(stk.empty()) cout << "YES" << endl;//栈判空
else cout << "NO" << endl;
}
}
}
堆是一种特殊的树形数据结构,通常用于实现优先队列等算法。在C++中,我们可以使用STL中的priority_queue来实现堆。
//堆排序
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int n,m;
int h[N] , size;
void down(int u)
{
int t = u;
if(u*2<=size&&h[u*2]<h[t]) t = u * 2;
if(u * 2 + 1 <= size && h[u * 2 + 1] < h[t]) t = u * 2 + 1;
if(u !=t)
{
swap(h[u] , h[t]);
down(t);
}
}
void up(int u)
{
while(u / 2 && h[u / 2] > h[u])
{
swap(h[u/2], h[u]);
u /= 2;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1;i<=n ; i++)
{
scanf("%d",&h[i]);
}
size = n;
for(int i=n/2;i;i --) down(i);
while(m--)
{
printf("%d ",h[1]);
h[1] = h[size];
size --;
down(1);
}
return 0;
}
并查集是一种用于处理不相交集合的数据结构,通常用于解决图论中的连通性问题。在C++中,我们可以使用并查集来实现。
(1)朴素并查集:
int p[N];
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
for (int i = 1; i <= n; i ++ ) p[i] = i;
p[find(a)] = find(b);
(2)维护size的并查集:
int p[N], size[N];
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
for (int i = 1; i <= n; i ++ )
{
p[i] = i;
size[i] = 1;
}
size[find(b)] += size[find(a)];
p[find(a)] = find(b);
(3)维护到祖宗节点距离的并查集:
int p[N], d[N];
int find(int x)
{
if (p[x] != x)
{
int u = find(p[x]);
d[x] += d[p[x]];
p[x] = u;
}
return p[x];
}
for (int i = 1; i <= n; i ++ )
{
p[i] = i;
d[i] = 0;
}
p[find(a)] = find(b);
d[find(a)] = distance;
哈希表是一种用于快速查找的数据结构,通常用于实现字典等功能。在C++中,我们可以使用STL中的unordered_map来实现哈希表。
(1) int h[N], e[N], ne[N], idx;
void insert(int x)
{
int k = (x % N + N) % N;
e[idx] = x;
ne[idx] = h[k];
h[k] = idx ++ ;
}
bool find(int x)
{
int k = (x % N + N) % N;
for (int i = h[k]; i != -1; i = ne[i])
if (e[i] == x)
return true;
return false;
}
(2)
int h[N];
int find(int x)
{
int t = (x % N + N) % N;
while (h[t] != null && h[t] != x)
{
t ++ ;
if (t == N) t = 0;
}
return t;
}
树是一种非线性数据结构,常用于实现搜索树、堆等算法。在C++中,我们可以使用指针或者STL中的set、map等容器来实现树。
#include <iostream>
using namespace std;
#define MAX_NODES 100
struct Node {
int value;
int children[MAX_NODES];
int numChildren;
};
Node tree[MAX_NODES];
int nextNode = 0;
void createNode(int value) {
tree[nextNode].value = value;
tree[nextNode].numChildren = 0;
nextNode++;
}
void addChild(int parentIndex, int childIndex) {
tree[parentIndex].children[tree[parentIndex].numChildren] = childIndex;
tree[parentIndex].numChildren++;
}
void printTree(int nodeIndex, int depth) {
for (int i = 0; i < depth; i++) {
cout << " ";
}
cout << tree[nodeIndex].value << endl;
for (int i = 0; i < tree[nodeIndex].numChildren; i++) {
printTree(tree[nodeIndex].children[i], depth + 1);
}
}
int main() {
createNode(1);
createNode(2);
createNode(3);
addChild(0, 1);
addChild(0, 2);
createNode(4);
createNode(5);
addChild(1, 3);
addChild(1, 4);
printTree(0, 0);
return 0;
}
通过以上的示例,我们可以看到如何使用C++来实现各种常见的数据结构,包括链表、队列、栈、堆、并查集、哈希表和树。希望本文能对你有所帮助。谢谢阅读!