数据结构(c++)

本文详细介绍了在软件开发中常见的数据结构,如链表、队列、栈、堆、并查集、哈希表和树,以及它们在C++中的实现方法,强调了选择适当数据结构对程序性能的影响。
摘要由CSDN通过智能技术生成

数据结构在计算机科学中扮演着至关重要的角色,它是存储和组织数据的基本方式。在软件开发中,了解和熟练掌握各种数据结构是非常重要的,因为选择合适的数据结构可以极大地影响程序的性能和效率。在本文中,我们将讨论一些常见的数据结构,包括链表、队列、栈、堆、并查集、哈希表和树。

链表是一种线性数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表可以是单向的,也可以是双向的。在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++来实现各种常见的数据结构,包括链表、队列、栈、堆、并查集、哈希表和树。希望本文能对你有所帮助。谢谢阅读!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值