基础数据结构——Stack, Queue, Vector, List

时间:2021-01-18 04:17:27

栈(Stack)

数组实现方式:

/***top表示当前的元素位置***/
initialize()
    top = -1;

inEmpty()
    return top == -1;

isFull()
    return top == Max - 1;

push(x)
    if isFull()
       error();
    top++;
    S[top] = x;

pop(x)
    if isEmpty()
        error();
    top--;
    return S[top + 1];

STL实现方式:

函数名 功能 复杂度
size() 返回栈的元素数 O(1)
top() 返回栈顶元素 O(1)
pop() 从栈中取出并删除元素 O(1)
push(x) 向栈中添加元素x O(1)
empty() 在栈为空时返回true O(1)

例题:Stack

  • 题意:用式子的逆波兰式(即中缀表示法)算出式子的最终答案
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <stack>
#include <cstdlib>
using namespace std;

char str[3];
stack <int> S;

int main()
{
    //freopen("1.txt", "r", stdin);
    int x, y, ans;
    while (!S.empty())
        S.pop();

    while (scanf("%s", str) != EOF)
    {
        if (str[0] == '+')
        {
            x = S.top(); S.pop();
            y = S.top(); S.pop();
            S.push(x + y);
        }
        else if (str[0] == '-')
        {
            x = S.top(); S.pop();
            y = S.top(); S.pop();
            S.push(y - x);
        }
        else if (str[0] == '*')
        {
            x = S.top(); S.pop();
            y = S.top(); S.pop();
            S.push(x * y);
        }
        else
            S.push(atoi(str));
    }

    printf("%d\n", S.top());
    return 0;
}

队列(Queue)

数组实现方式:

initialize()
    head = tail = 0;

isEmpty()
    return head == tail

enqueue(x)
    if isFull()
        error();
    Q[tail] = x;
    tail = (tail + 1) % Max;

dequeue(x)
    if isEmpty()
        error();
    x = Q[head];
    head = (head + 1) % Max;
    return x;

STL 实现方式:

函数名 功能 复杂度
size() 返回队列的元素数 O(1)
front() 返回对头的元素 O(1)
pop() 从队列中取出并删除元素 O(1)
push(x) 向队列中添加元素x O(1)
empty() 在队列为空时返回true O(1)

例题:Queue

  • 题意:OS的时间片轮转法,即每个任务有一个所需运行时间,每次轮转到该任务给 q 时间来运行,时间片结束则强制换下一个任务,直到所有任务结束。输出任务结束时间顺序。
#include <cstdio>
#include <iostream>
#include <queue>
#include <algorithm>
#include <cmath>
using namespace std;

int main()
{
    int n, q, t;
    string name;
    queue <pair<string, int> > Q;

    scanf("%d %d", &n, &q);
    for (int i = 0; i < n; i++)
    {
        cin >> name >> t;
        Q.push(make_pair(name, t));
    }

    pair<string, int> u;
    int time = 0;

    while (!Q.empty())
    {
        u = Q.front();
        Q.pop();
        int tmp = min(u.second, q);
        u.second -= tmp;
        time += tmp;

        if (u.second > 0)
            Q.push(u);
        else
            cout << u.first << " " << time << endl;
    }
    return 0;
}

链表(Linked List)

双向链表(Doubly Linked List )

数组实现方式:

struct Node
{
    int key;
    Node *prev, *next;
}

Node *nil;

void init()
{
    nil = (Node *) malloc (sizeof(Node));
    nil->prev = nil;
    nil->next = nil;
}

void insert(int key)
{
    Node *x = (Node *) malloc (sizeof(Node));
    x->key = key;

    x->next = nil->next;
    nil->next->prev = x;
    nil->next = x;
    x->prev = nil; 
}

Node* listSearch(int key)
{
    Node *cur = nil->next;
    while (cur != nil && cur->key != key)
    {
        cur = cur->next;
    }
    return cur;
}

void delectNode(Node *t)
{
    if (t == Nil) return;
    t->prev->next = t->next;
    t->next->prev = t->prev;
    free(t);
}

void deleteFirst()
{
    deleteNode(nil->next);
}

void deleteLast()
{
    deleteNode(nil->prev);
}

void deleteKey(int key)
{
    deleteNode(listSearch(key));
}

单向链表(Vector)

函数名 功能 复杂度
size() 返回向量的元素数 O(1)
push_back(x) 在向量末尾添加元素x O(1)
pop_back() 删除向量的最后一个元素 O(1)
begin() 返回指向向量开头的迭代器 O(1)
end() 返回指向向量末尾(最后一个元素后一个位置)的迭代器 O(1)
insert(p,x) 在向量的位置p出插入元素x O(n)
erase(p) 删除向量中位置p的元素 O(n)
clear() 删除向量中所有元素 O(n)
遍历方式1for (int i = 0; i < v.size(); i++)
    do(v[i]);

遍历方式2vector <int>::iterator it;
for (it = v.begin(); it != v.end(); it++)
    do(*it);

二维动态数组:
vector <vector<int> > v;
for (int i = 0; i < v.size(); i++)
    for (int j = 0; j < v[i].size(); j++)
    do(v[i][j])

赋值:
v.push_back(1);             //1
v.push_back(2);             //1,2
v[1] = 3;                   //1,3
v.insert(v.begin() + 2, 4)  //1,3,4
v.erase(v.begin() + 1)      //1,4

双向链表(List)

函数名 功能 复杂度
size() 返回表的元素数 O(1)
begin() 返回指向表开头的迭代器 O(1)
end() 返回指向表末尾(最后一个元素后一个位置)的迭代器 O(1)
push_front(x) 在表的开头添加元素x O(1)
push_back(x) 在表的末尾添加元素x O(1)
pop_front() 删除位于表开头的元素 O(1)
pop_back() 删除位于表末尾的元素 O(1)
insert(p,x) 在表的位置p出插入元素x O(1)
erase(p) 删除表中位置p的元素 O(1)
clear() 删除表中所有元素 O(n)

例题:Doubly Linked List

题意:

  • insert x: 在链表开头添加含有键值x的结点
  • delete x: 删除第1个含有键值x的结点
  • deleteFirst: 删除链表的表头结点
  • deleteLast: 删除链表的表尾结点
#include <cstdio>
#include <iostream>
#include <queue>
#include <algorithm>
#include <cmath>
#include <list>
#include <cstring>
using namespace std;

int main()
{
    list <int> l;
    list <int> :: iterator it;
    char op[10];
    int v, q;
    scanf("%d", &q);

    while (q--)
    {
        scanf("%s", op);
        if (op[0] == 'i')
            {
                scanf("%d", &v);
                l.push_front(v);
            }
        else if (strlen(op) == 10)   //deleteLast
            l.pop_back();
        else if (strlen(op) == 11)   //deleteFirst
            l.pop_front();
        else
        {
            scanf("%d", &v);

            for (it = l.begin(); it != l.end(); it++)
            {
                if (*it == v)
                {
                    l.erase(it);
                    break;
                }
            }
        }
    }

    it = l.begin();
    printf("%d", *it);
    it++;
    for (; it != l.end(); it++)
        printf(" %d", *it);
    printf("\n");
    return 0;
}