
typedef struct DoubleLinkListNode {
struct DoubleLinkListNode *prev;
struct DoubleLinkListNode *next;
int val;
} DLNode;
typedef struct {
DLNode *head;
DLNode *tail;
int length;
} Deque;
typedef struct {
Deque *left;
Deque *right;
} FrontMiddleBackQueue;
DLNode* doubleLinkListNodeCreate(int val) {
DLNode *obj = (DLNode *)malloc(sizeof(DLNode));
obj->prev = NULL;
obj->next = NULL;
obj->val = val;
return obj;
}
Deque* dequeCreate() {
Deque *obj = (Deque *)malloc(sizeof(Deque));
obj->head = doubleLinkListNodeCreate(-1);
obj->tail = doubleLinkListNodeCreate(-1);
obj->head->next = obj->tail;
obj->tail->prev = obj->head;
obj->length = 0;
return obj;
}
bool dequePushFront(Deque* obj, int val) {
assert(obj != NULL);
DLNode *node = doubleLinkListNodeCreate(val);
node->next = obj->head->next;
node->next->prev = node;
node->prev = obj->head;
obj->head->next = node;
obj->length++;
return true;
}
bool dequePushBack(Deque* obj, int val) {
assert(obj != NULL);
DLNode *node = doubleLinkListNodeCreate(val);
node->next = obj->tail;
node->prev = obj->tail->prev;
node->prev->next = node;
obj->tail->prev = node;
obj->length++;
return true;
}
int dequeFront(Deque* obj) {
assert(obj != NULL && obj->length != 0);
return obj->head->next->val;
}
int dequeBack(Deque* obj) {
assert(obj != NULL && obj->length != 0);
return obj->tail->prev->val;
}
int dequePopFront(Deque* obj) {
assert(obj != NULL && obj->length != 0);
int val = obj->head->next->val;
DLNode *node = obj->head->next;
obj->head->next = node->next;
node->next->prev = obj->head;
obj->length--;
free(node);
return val;
}
int dequePopBack(Deque* obj) {
assert(obj != NULL && obj->length != 0);
int val = obj->tail->prev->val;
DLNode *node = obj->tail->prev;
node->prev->next = obj->tail;
obj->tail->prev = node->prev;
obj->length--;
free(node);
return val;
}
int dequeLength(Deque* obj) {
assert(obj != NULL);
return obj->length;
}
bool dequeEmpty(Deque *obj) {
assert(obj != NULL);
return obj->length == 0;
}
void dequeFree(Deque *obj) {
DLNode *curr = obj->head;
while (curr) {
DLNode *node = curr;
curr = curr->next;
free(node);
}
free(obj);
}
FrontMiddleBackQueue* frontMiddleBackQueueCreate() {
FrontMiddleBackQueue *obj = (FrontMiddleBackQueue *)malloc(sizeof(FrontMiddleBackQueue));
obj->left = dequeCreate();
obj->right = dequeCreate();
return obj;
}
void frontMiddleBackQueuePushFront(FrontMiddleBackQueue* obj, int val) {
dequePushFront(obj->left, val);
if (dequeLength(obj->left) == dequeLength(obj->right) + 2) {
dequePushFront(obj->right, dequePopBack(obj->left));
}
}
void frontMiddleBackQueuePushMiddle(FrontMiddleBackQueue* obj, int val) {
if (dequeLength(obj->left) == dequeLength(obj->right) + 1) {
dequePushFront(obj->right, dequePopBack(obj->left));
}
dequePushBack(obj->left, val);
}
void frontMiddleBackQueuePushBack(FrontMiddleBackQueue* obj, int val) {
dequePushBack(obj->right, val);
if (dequeLength(obj->left) + 1 == dequeLength(obj->right)) {
dequePushBack(obj->left, dequePopFront(obj->right));
}
}
int frontMiddleBackQueuePopFront(FrontMiddleBackQueue* obj) {
if (dequeEmpty(obj->left)) {
return -1;
}
int val = dequePopFront(obj->left);
if (dequeLength(obj->left) + 1 == dequeLength(obj->right)) {
dequePushBack(obj->left, dequePopFront(obj->right));
}
return val;
}
int frontMiddleBackQueuePopMiddle(FrontMiddleBackQueue* obj) {
if (dequeEmpty(obj->left)) {
return -1;
}
int val = dequePopBack(obj->left);
if (dequeLength(obj->left) + 1 == dequeLength(obj->right)) {
dequePushBack(obj->left, dequePopFront(obj->right));
}
return val;
}
int frontMiddleBackQueuePopBack(FrontMiddleBackQueue* obj) {
if (dequeEmpty(obj->left)) {
return -1;
}
int val = 0;
if (dequeEmpty(obj->right)) {
val = dequePopBack(obj->left);
} else {
val = dequePopBack(obj->right);
if (dequeLength(obj->left) == dequeLength(obj->right) + 2) {
dequePushFront(obj->right, dequePopBack(obj->left));
}
}
return val;
}
void frontMiddleBackQueueFree(FrontMiddleBackQueue* obj) {
dequeFree(obj->left);
dequeFree(obj->right);
free(obj);
}