码迷,mamicode.com
首页 > 其他好文 > 详细

每日一题15:双端队列与自调整表

时间:2015-04-05 10:36:04      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:双端队列   自调整表   

双端队列是一种插入和删除可以既可以在表头也可以表尾进行的一种数据结构,四种基本操作分别为:
push:在表头插入
pop:在表头删除
insert:在表尾插入
eject:在表尾删除
每一种操作的复杂度都为O(1)。通过组合不同插入和删除,双端队列可以作为栈使用,也可以作为队列使用:

#include "stdafx.h"
#include <iostream>

using namespace std;

struct deque_node
{
    int val;
    deque_node* next;
    deque_node* pre;
};

struct my_deque
{
    int count;
    deque_node* head;
    deque_node* tail;
};

my_deque* create_empty_deque()
{
    my_deque* deq = new my_deque;
    deq->head = NULL;
    deq->tail = NULL;
    deq->count = 0;
    return deq;
}

deque_node* create_deque_node(int val)
{
    deque_node* node = new deque_node;
    node->val = val;
    node->pre = NULL;
    node->next = NULL;
    return node;
}

void push(my_deque** deq,int val)
{
    deque_node* node = create_deque_node(val);
    if((*deq)->count == 0)
    {
        (*deq)->tail = node;
        (*deq)->head = node;
    }
    else
    {
        node->next = (*deq)->head;
        (*deq)->head->pre = node;
        (*deq)->head = node;
    }
    ++(*deq)->count;
}

bool pop(my_deque** deq,int& val)
{
    if((*deq)->count == 0) return false;
    if((*deq)->count == 1)
    {
        val = (*deq)->head->val;
        delete (*deq)->head;
        (*deq)->head = (*deq)->tail = NULL;
    }
    else
    {
        deque_node* p = (*deq)->head;
        (*deq)->head = p->next;
        (*deq)->head->pre = NULL;
        val = p->val;
        delete p;
    }
    --(*deq)->count;
    return true;
}

void insert(my_deque** deq,int val)
{
    deque_node* node = create_deque_node(val);
    if((*deq)->count == 0)
    {
        (*deq)->head = node;
    }
    else
    { 
        (*deq)->tail->next = node;
        node->pre = (*deq)->tail;
    }
    (*deq)->tail = node;
    ++(*deq)->count;
}

bool eject(my_deque** deq,int& val)
{
    if((*deq)->count == 0) return false;
    if((*deq)->count == 1)
    {
        val = (*deq)->head->val;
        delete (*deq)->head;
        (*deq)->head = (*deq)->tail = NULL;
    }
    else
    {
        deque_node* p = (*deq)->tail;
        p->pre->next = NULL;
        (*deq)->tail = p->pre;
        val = p->val;
        delete p;
    }
    --(*deq)->count;
    return true;
}

void display(const my_deque* deq)
{
    deque_node* p = deq->head;
    while(p)
    {
        cout<<p->val<<‘ ‘;
        p = p->next;
    }
    cout<<endl;
}

void reverse_display(const my_deque* deq)
{
    deque_node* p = deq->tail;
    while(p)
    {
        cout<<p->val<<‘ ‘;
        p = p->pre;
    }
    cout<<endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    my_deque* deq = create_empty_deque();
    for (int i = 1; i < 6; ++i)
    {
        push(&deq,i);
    }
    display(deq);
    reverse_display(deq);
    cout<<deq->count<<endl;
    for (int i = 1; i < 6; ++i)
    {
        int val;
        if(pop(&deq,val))
            cout<<val<<‘ ‘;
    }
    cout<<endl;
    cout<<deq->count<<endl;

    for (int i = 1; i < 6; ++i)
    {
        insert(&deq,i);
    }
    display(deq);
    reverse_display(deq);
    cout<<deq->count<<endl;
    for (int i = 1; i < 6; ++i)
    {
        int val;
        if(eject(&deq,val))
            cout<<val<<‘ ‘;
    }
    cout<<endl;
    cout<<deq->count<<endl;
    return 0;
}

技术分享
自调整表就像是一种规则的表,但是它的插入与删除操作都在表头进行,同时当任一个元素被find访问时,它就被移到表头而不改变其它元素的相对位置。基于链表实现的自调整表比较简单,基于数组实现的则需要更多的小心。

#include "stdafx.h"
#include <iostream>

using namespace std;

const int null_slot = -2;
const int end_slot = -1;

struct list_node
{
    int val;
    int next;
};

struct self_adjust_list
{
    int capacity;
    int size;
    int head;
    list_node* vals;
};

self_adjust_list* create(int capacity)
{
    self_adjust_list* sal = new self_adjust_list;
    sal->vals = new list_node[capacity];
    memset(sal->vals,0,capacity*sizeof(list_node));
    for (int i = 0; i < capacity; ++i)
    {
        sal->vals[i].next = null_slot;
    }
    sal->size = 0;
    sal->head = 0;
    sal->capacity = capacity;
    return sal;
}

bool find(self_adjust_list** sal,int val)
{
    if((*sal)->size == 0) return false;
    int cur = (*sal)->head;
    list_node* p = (*sal)->vals;
    int pre = -1;
    while(cur != end_slot && p[cur].val != val)
    {
        pre = cur;
        cur = p[cur].next;
    }
    if(cur == (*sal)->head) return true;
    if(cur != end_slot)
    {
        p[pre].next = p[cur].next;
        p[cur].next = (*sal)->head;
        (*sal)->head = cur;
        return true;
    }
    return false;
}

void push(self_adjust_list** sal,int val)
{
    if(find(sal,val)) return;

    if((*sal)->size == 0)
    {
        (*sal)->vals[0].val = val;
        (*sal)->vals[0].next = end_slot;

    }
    else
    {
        int i = 0;
        for (; i < (*sal)->capacity; ++i)
        {
            if((*sal)->vals[i].next == null_slot)
                break;
        }
        (*sal)->vals[i].next = (*sal)->head;
        (*sal)->vals[i].val = val;
        (*sal)->head = i;
    }

    ++(*sal)->size;
}

bool pop(self_adjust_list** sal,int &val)
{
    if((*sal)->size < 1) return false;

    list_node* p = &(*sal)->vals[(*sal)->head];
    val = p->val;
    if((*sal)->size > 1)
    {
        (*sal)->head = p->next;
        p->next = null_slot;
    }
    else
    {
        (*sal)->head = 0;
    }
    --(*sal)->size;
    return true;
}


int _tmain(int argc, _TCHAR* argv[])
{
    self_adjust_list* sal = create(20);
    for (int i = 1; i < 6; ++i)
        push(&sal,i);
    cout<<sal->size<<endl;
    for (int i = 10; i > 0; --i)
    {
        cout<<find(&sal,i)<<‘ ‘;
    }
    cout<<endl;
    for (int i = 1; i < 20; ++i)
    {
        int val;
        if(pop(&sal,val))
            cout<<val<<‘ ‘;
    }
    cout<<endl;
    cout<<sal->size<<endl;
    return 0;
}

技术分享

每日一题15:双端队列与自调整表

标签:双端队列   自调整表   

原文地址:http://blog.csdn.net/liao_jian/article/details/44885815

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