码迷,mamicode.com
首页 > 编程语言 > 详细

区别deque vector 和数组

时间:2014-11-14 19:24:03      阅读:240      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   io   color   ar   os   sp   for   

Leetcode更新到155题了,这个easy的题acceptance却不高,我好奇的点开了它。

 

Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

  • push(x) -- Push element x onto stack.
  • pop() -- Removes the element on top of the stack.
  • top() -- Get the top element.
  • getMin() -- Retrieve the minimum element in the stack.

果然easy嘛,そして:

 

class MinStack {
    struct node
    {
        int value;
        node * next;
        node(int v, node * n=0):value(v),next(n){}
    };
    node * h;
    node * min;
    
public:
    MinStack():h(0), min(0){}
    void push(int x) {
        h = new node (x, h);
        if(!min || min->value >= x)
            min = new node (x, min);
    }

    void pop() {
        if(h)
        {
            node * p;
            if(h->value == min->value)
            {
                p = min;
                min = min->next;
                delete p;
            }
            p = h;
            h = h->next;
            delete p;
        }
    }

    int top() {
        if(h)
            return h->value;
        throw;
    }

    int getMin() {
        if(min)
            return min->value;
        throw;
    }
};

    据说通用的STL容器非常多虑,多线程神马的都考虑了进去,静态链接也会把从来不调用的函数加进去,因此我习惯于手动实现容器。XX怎么回事:memory limited error!N个next指针居然就不耐了也太傲娇了!

    那么不用链式结构了,改用数组吧。就用vector试试。

 

class MinStack {
    vector<int> h;
    vector<int> min;
    
public:
    void push(int x) {
        h.push_back(x);
        if (min.empty() || min.back() >= x)
            min.push_back(x);
    }

    void pop() {
        if (h.back() == min.back())
            min.pop_back();
        h.pop_back();
    }

    int top() {
        return h.back();
    }

    int getMin() {
        return min.back();
    }
};    

    XX,又是mle!最后看到别人用deque,做法大同小异,就抄了过来。好在STL里的函数名称比较统一,vector和deque的抽插都叫做push_back和pop_back,改下定义就好啦:

class MinStack {
    deque<int> h;
    deque<int> min;
    
public:
    void push(int x) {
        h.push_back(x);
        if(min.empty() || min.back() >= x)
            min.push_back(x);
    }

    void pop() {
        if(h.back() == min.back())
            min.pop_back();
        h.pop_back();
    }

    int top() {
        return h.back();
    }

    int getMin() {
        return min.back();
    }
};

    查了下资料,又涨知识了!deque采用数组和链表的这种策略,初始先分配一块连续内存,不够了再分配一块,然后这些先后分配的内存通过指针“通通连起来”,逻辑上就是连续的空间了。这种东西早就想写一个,没想到STL已经提供了,而且STL中的stack和queue等容器底下正是它!perfect!

   现在比较下数组、vector和deque:

   1:原理:

    数组:连续且固定的空间;

    vector:连续但不固定的空间,原空间不够了将会调用allocator进行realloc,然后通过uninitialized_copy复制旧内容。

    deque:连续的链式空间,空间不够则分配新的空间,每个内存块呈链式(不是新鲜事吧?从前学数据结构,有这样实现过string,学操作系统,其中文件管理也有用链式方法的)。

 

    2:增长方向:

    数组:长不大

    vector:逻辑上是ForwardIncremental的

    deque:显然是双向的了。

 

    3:性能:

   用下面这段简单的代码测试下,因为我用的是上上个五年计划的时候出的Thinkpad X61,N=100000000,sizeof(x

) = 12B差不多是极限了。

  用int测试时,输出4  6;

  用struct测试时,deque的循环输出7,vector在插入过程中直接bad_alloc,原因是找不到足够大的连续内存了。

 

#include <cstdlib>
#include <ctime>
#include <deque>
#include <vector>
#include <iostream>
using namespace std;

struct s
{
    int v;
    int a[2];
    s(int i):v(i){}
    ~s()
    {
        //make it a non-trivial destructor;
    }
};

main()
{
    typedef s T;
    int const N = 100000000;
    int i;
    double start;
    deque<T> d;
    vector<T> v;
    start = time(0);
    for(i=0; i<N; i++)
        d.push_back(T(i));
    for(i=0; i<N; i++)
        d.pop_back();
    cout <<time(0) - start<<endl;
    start = time(0);
    for(i=0; i<N; i++)
        v.push_back(T(i));
    for(i=0; i<N; i++)
        v.pop_back();
    cout <<time(0) - start<<endl;
}

    

    当然并非以后就弃vector不用了,如果每次访问的内存地址比较跳跃,deque的效率必然就不行了,因为要跳到另一个块上,it++当然不行,至少需要访问两次内存了。果然存在即有理。

 

区别deque vector 和数组

标签:des   style   blog   io   color   ar   os   sp   for   

原文地址:http://www.cnblogs.com/zhchngzng/p/4097798.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!