双端队列是一种插入和删除可以既可以在表头也可以表尾进行的一种数据结构,四种基本操作分别为:
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;
}
原文地址:http://blog.csdn.net/liao_jian/article/details/44885815