队列的实现
思路:用链表实现队列,先定义一个结构体QNode,里面存放数据域和指针域,因为队列只在队头和队尾进行操作,可以让两个指针分别指向队头和队尾,所以再定义一个结构体Queue里面存放两个QNode结构体的指针——front和_rear,让这两个结构体一个指向链表的头一个指向尾。然后通过Queue这个结构体里面的两个指针来对队列进行各种操作。
还是上图吧
代码的实现
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <malloc.h>
// 链式结构:表示队列
typedef int QDataType;
typedef struct QNode
{
struct QNode* _pNext;
QDataType _data;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* _front;
QNode * _rear;
}Queue;
// 初始化队列
void QueueInit(Queue* q)
{
assert(q);
q->_front=q->_rear=NULL;
}
// 队尾入队列
void QueuePush(Queue* q, QDataType data)
{
assert(q);
QNode* newnode=(QNode*)malloc(sizeof(QNode));
newnode->_data=data;
newnode->_pNext=NULL;
if(q->_rear==NULL)
{
q->_rear= q->_front=newnode;
}
else
{
q->_rear->_pNext=newnode;
q->_rear=newnode;
}
}
// 队头出队列
void QueuePop(Queue* q)
{
assert(q);
QNode *p=q->_front->_pNext;
free(q->_front);
q->_front=p;
if(q->_front==NULL)
{
q->_rear=NULL;
}
}
// 获取队列头部元素
QDataType QueueFront(Queue* q)
{
assert(q);
return q->_front->_data;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* q)
{
assert(q);
return q->_rear->_data;
}
// 获取队列中有效元素个数
int QueueSize(Queue* q)
{
assert(q);
int count=0;
QNode*p=q->_front;
while(p!=NULL)
{
p=p->_pNext;
++count;
}
return count;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q)
{
assert(q);
return q->_front==NULL? 1:0;
}
// 销毁队列
void QueueDestroy(Queue* q)
{
QNode *p=q->_front;
while(p!=NULL)
{
QNode *next=p->_pNext;
free(p);
p=next;
}
q->_front=q->_rear=NULL;
}
void QueuePrint(Queue *q)
{
assert(q);
QNode *cur=q->_front;
while(cur!=NULL)
{
printf("%d ",(cur->_data));
cur=cur->_pNext;
}
printf("\n");
}
void test()
{
Queue q;
QueueInit(&q);
QueuePush(&q, 1);
QueuePush(&q, 2);
QueuePush(&q, 3);
QueuePush(&q, 5);
// QueuePop(&q);
QueuePrint(&q);
printf("队头的元素: %d\n",QueueFront(&q));
printf("队尾的元素: %d\n",QueueBack(&q));
printf("队列中元素个数:%d\n",QueueSize(&q));
QueueDestroy(& q);
printf("1:空 0:非空 队列是否为空 %d\n",QueueEmpty(&q));
}
int main()
{
test();
return 0;
}
栈的实现
两个栈实现队列
思路:这里就只讲一下push和pop吧,栈是后进先出,而队列是先进先出,所以要想用栈实现队列可以定义两个栈,一个是push的一个是pop的,入数据进入push栈,出数据从pop栈出,如果pop栈为空,则将push栈里面的数据出栈然后入栈到pop中去。。。。。似乎说的有点绕
// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{ STDataType* myarr;
int _top; // 栈顶
int _capacity; // 容量
}Stack;
void StackInit(Stack* ps)//创建空数组
{
assert(ps);
ps->_capacity = 10;
ps->_top = 0;
ps->myarr = (STDataType*)malloc(sizeof(STDataType)*ps->_capacity);
//if (ps->myarr == NULL)
// return NULL;
}
void StackCapacity(Stack* ps)//扩容
{
assert(ps);
if (ps->_top == ps->_capacity)
{
if (ps->myarr == 0)
ps->_capacity = 2;
ps->myarr= (STDataType *)realloc(ps->myarr, ps->_capacity*sizeof(STDataType)* 2);
ps->_capacity = ps->_capacity * 2;
}
}
void StackPush(Stack* ps, STDataType x)//入栈
{
assert(ps);
StackCapacity(ps);
ps->myarr[ps->_top] = x;
ps->_top++;
}
void Stackprint(Stack *ps)//打印栈
{
assert(ps);
Stack *p = ps;
for (int i = 0; i < ps->_top; i++)
{
printf("%d ", ps->myarr[i]);
}printf("\n");
}
void StackPop(Stack* ps)//出栈
{
assert(ps);
if (ps->_top == 0)
{
//printf("栈为空\n");
return;
}
//STDataType s=ps->myarr[ps->_top-1];
(ps->_top)--;
}
void StackEmpty(Stack* ps)//清空栈
{
assert(ps);
ps->_capacity = 0;
ps->_top = 0;
free(ps->myarr);
//if (ps->_top == 0)
//printf("栈为空");
}
int StackSize(Stack* ps)//输出栈的大小
{
assert(ps);
//printf("栈的长度为%d\n",ps->_top);
return ps->_top;
}
STDataType StackTop(Stack* ps)
{
assert(ps);
/*if (ps->_top == 0)
{
printf("栈为空\n");
return ;
}*/
//printf("栈顶的内容%d\n", ps->myarr[ps->_top-1]);
return ps->myarr[ps->_top-1];
}
typedef struct {
Stack s1;//push
Stack s2;//pop
} MyQueue;
/** Initialize your data structure here. */
MyQueue* myQueueCreate() {
MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
StackInit(&(obj->s1));
StackInit(&(obj->s2));
return obj;
}
/** Push element x to the back of queue. */
void myQueuePush(MyQueue* obj, int x) {
StackPush(&obj->s1,x);
}
/** Removes the element from in front of queue and returns that element. */
int myQueuePop(MyQueue* obj) {
//如果s2(pop)栈为空,则需要将s1里面的数据倒过来,然后pop
if(StackSize(&obj->s2)==0)
{
while(StackSize(&obj->s1)>0)
{
StackPush(&obj->s2,StackTop(&obj->s1));
StackPop(&obj->s1);
}
}
STDataType s=StackTop(&obj->s2);
StackPop(&obj->s2);
return s;
}
/** Get the front element. */
int myQueuePeek(MyQueue* obj) {
if(StackSize(&obj->s2)==0)
{
while(StackSize(&obj->s1)>0)
{
StackPush(&obj->s2,StackTop(&obj->s1));
StackPop(&obj->s1);
}
}
return StackTop(&obj->s2);
}
/** Returns whether the queue is empty. */
bool myQueueEmpty(MyQueue* obj) {
return StackSize(&(obj->s1))==0&&StackSize(&(obj->s2))==0;
}
void myQueueFree(MyQueue* obj) {
StackEmpty(&(obj->s1));
StackEmpty(&(obj->s2));
}
两个队列实现栈
定义两个队列,一个是空队列empty一个是有数据的队列noempty,入栈是将数据存放到有数据的队列,出栈是需要将noempty里面除了队尾的元素,其他都要放到empty中,然后将noempty里面的元素出队列。
// 链式结构:表示队列
typedef int QDataType;
typedef struct QNode
{
struct QNode* _pNext;
QDataType _data;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* _front;
QNode * _rear;
}Queue;
// 初始化队列
void QueueInit(Queue* q)
{
assert(q);
q->_front=q->_rear=NULL;
}
// 队尾入队列
void QueuePush(Queue* q, QDataType data)
{
assert(q);
QNode* newnode=(QNode*)malloc(sizeof(QNode));
newnode->_data=data;
newnode->_pNext=NULL;
if(q->_rear==NULL)
{
q->_rear= q->_front=newnode;
}
else
{
q->_rear->_pNext=newnode;
q->_rear=newnode;
}
}
// 队头出队列
void QueuePop(Queue* q)
{
assert(q);
QNode *p=q->_front->_pNext;
free(q->_front);
q->_front=p;
if(q->_front==NULL)
{
q->_rear=NULL;
}
}
// 获取队列头部元素
QDataType QueueFront(Queue* q)
{
assert(q);
return q->_front->_data;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* q)
{
assert(q);
return q->_rear->_data;
}
// 获取队列中有效元素个数
int QueueSize(Queue* q)
{
assert(q);
int count=0;
QNode*p=q->_front;
while(p!=NULL)
{
p=p->_pNext;
++count;
}
return count;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q)
{
assert(q);
return q->_front==NULL? 1:0;
}
// 销毁队列
void QueueDestroy(Queue* q)
{
QNode *p=q->_front;
while(p!=NULL)
{
QNode *next=p->_pNext;
free(p);
p=next;
}
q->_front=q->_rear=NULL;
}
typedef struct {
//定义两个队列
Queue q1;
Queue q2;
} MyStack;
/** Initialize your data structure here. */
MyStack* myStackCreate() {
MyStack *obj=(MyStack*)malloc(sizeof(MyStack));
QueueInit(&(obj->q1));
QueueInit(&(obj->q2));
return obj;
}
/** Push element x onto stack. */
void myStackPush(MyStack* obj, int x) {
if(QueueEmpty(&(obj->q1))==1)//q1为空
{
QueuePush(&(obj->q2),x);
}
else
{
QueuePush(&(obj->q1),x);
}
}
/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack* obj) {
Queue* empty=&obj->q1;
Queue* noempty=&obj->q2;
if(QueueEmpty(&(obj->q1))==0)//q1不为空
{
empty=&obj->q2;
noempty=&obj->q1;
}
while(QueueSize((noempty))>1)
{
QueuePush((empty),QueueFront((noempty)));
QueuePop((noempty));
}
int q=QueueFront(noempty);
QueuePop(noempty);
return q;
}
/** Get the top element. */
int myStackTop(MyStack* obj) {
Queue empty=obj->q1;
Queue noempty=obj->q2;
if(QueueEmpty(&(obj->q1))==0)//q1不为空
{
empty=obj->q2;
noempty=obj->q1;
}
return QueueBack(&(noempty));
}
/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&(obj->q1))&&QueueEmpty(&(obj->q2));
}
void myStackFree(MyStack* obj) {
QueueDestroy(&(obj->q1));
QueueDestroy(&(obj->q2));
// free(&MyStack);
}