【leetcode】225. 用队列实现栈

用队列实现栈 题目链接

【leetcode】225. 用队列实现栈_第1张图片
【leetcode】225. 用队列实现栈_第2张图片

  在满足题目要求(队列的基本操作)的前提下,完成进阶要求(也就是使用一个队列实现栈),只能使用数组(只有队列操作的顺序表)实现队列

使用数组或者循环链表实现队列(循环队列)也可以完成进阶要求,不过我不确定这是否满足题目要求(peek/pop from front),使用循环队列看起来确实是从头节点开始取值的,但问题是它一下子就能就能取到尾节点,出队列也是一下子找到尾结点以及新的尾结点,感觉有点取巧。

如果坚持用不循环链表实现队列,只能给队列增加一个获取尾节点方法Rear(Queue*)和尾删方法PopRear(Queue*),不过很显然这样就不满足题目要求了,说白了就是不能称之为队列。

typedef int valuetype;
typedef struct QueueNode {
	valuetype val;
	struct QueueNode* next;
} QueueNode;

typedef struct Queue {
	int size;
	QueueNode* front;
    // 未使用rear,因为用了rear则不满足题目要求:peek/pop from front
	QueueNode* rear;
} Queue;
void Init(Queue* queue);

void Push(Queue* queue, valuetype val);
void Pop(Queue* queue);
valuetype Front(Queue* queue);
valuetype Rear(Queue* queue);

int Size(Queue* queue);
bool Empty(Queue* queue);
void Destroy(Queue* queue);


typedef struct {
    Queue queue1; 
    Queue queue2; 
} MyStack;


MyStack* myStackCreate() {
    MyStack* stack = (MyStack*)malloc(sizeof(MyStack));
    Init(&stack->queue1);
    Init(&stack->queue2);
    return stack;
}

void myStackPush(MyStack* obj, int x) {
    assert(obj);
    Push(&obj->queue1, x);
}

int myStackPop(MyStack* obj) {
    assert(obj);
    bool empty = Empty(&obj->queue1);
    Queue* emptyQueue = empty ? &obj->queue1 : &obj->queue2;
    Queue* nonEmptyQueue = !empty ? &obj->queue1 : &obj->queue2;
    while (Size(nonEmptyQueue) > 1) {
        Push(emptyQueue, Front(nonEmptyQueue));
        Pop(nonEmptyQueue);
    }
    int top = Front(nonEmptyQueue);
    Pop(nonEmptyQueue);
    return top;
}

int myStackTop(MyStack* obj) {
    assert(obj);
    bool empty = Empty(&obj->queue1);
    Queue* emptyQueue = empty ? &obj->queue1 : &obj->queue2;
    Queue* nonEmptyQueue = !empty ? &obj->queue1 : &obj->queue2;
    while (Size(nonEmptyQueue) > 1) {
        Push(emptyQueue, Front(nonEmptyQueue));
        Pop(nonEmptyQueue);
    }
    int top = Front(nonEmptyQueue);
    Push(emptyQueue, top);
    Pop(nonEmptyQueue);
    return top;
}

bool myStackEmpty(MyStack* obj) {
    assert(obj);
    return Empty(&obj->queue1) && Empty(&obj->queue2);
}

void myStackFree(MyStack* obj) {
    assert(obj);
    Destroy(&obj->queue1);
    Destroy(&obj->queue2);
    free(obj);
}

/**
 * Your MyStack struct will be instantiated and called as such:
 * MyStack* obj = myStackCreate();
 * myStackPush(obj, x);
 
 * int param_2 = myStackPop(obj);
 
 * int param_3 = myStackTop(obj);
 
 * bool param_4 = myStackEmpty(obj);
 
 * myStackFree(obj);
*/

void Init(Queue* queue) {
	assert(queue);
	queue->size = 0;
	queue->front = NULL;
	queue->rear = NULL;
}


void Push(Queue* queue, valuetype val) {
	assert(queue);
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL) {
		perror("Push(Queue*, valuetype) malloc failed.");
		return;
	}
	newnode->val = val; newnode->next = NULL;
	if (queue->size == 0) {
		queue->front = queue->rear = newnode;
	}
	else {
		queue->rear->next = newnode;
		queue->rear = newnode;
	}
	queue->size++;
}

void Pop(Queue* queue) {
	assert(queue && queue->size > 0);
	QueueNode* newfront = queue->front->next;
	free(queue->front);
	queue->front = newfront;
	queue->size--;
	
	if (queue->size == 0) {
		queue->rear = NULL;
	}
}


valuetype Front(Queue* queue) {
	assert(queue && queue->size > 0);
	return queue->front->val;
}

valuetype Rear(Queue* queue) {
	assert(queue && queue->size > 0);
	return queue->rear->val;
}


int Size(Queue* queue) {
	assert(queue);
	return queue->size;
}

bool Empty(Queue* queue) {
	assert(queue);
	return queue->size == 0;
}

void Destroy(Queue* queue) {
	assert(queue);
	QueueNode* node = queue->front;
	while (node) {
		QueueNode* next = node->next;
		free(node);
		node = next;
	}
	queue->size = 0;
	queue->front = queue->rear = NULL;
}

你可能感兴趣的:(Data,Structure,and,Algorithm,C语言,刷题,leetcode,算法,数据结构,c语言)