C语言栈和队列的相互实现以及循环队列的实现

232. 用栈实现队列 - 力扣(LeetCode)用两个栈来实现队列的功能,我们用其中一个栈来入数据,另一个来出数据,分别定义为pushst和popst,用来实现入栈时,只给pushst里面入数据,实现出栈时,只出popst里的数据,注意的是当popst为空时,要将pushst里的数据放到popst里去,再出栈。

就是用C语言的话,还得自己写个栈。

代码实现如下:

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;//栈顶位置
	int capacity;//容量

}ST;

void STInit(ST* ps);//初始化
void STDestroy(ST* ps);//销毁
void STPush(ST* ps, STDataType x);//插入
void STPop(ST* ps);//删除
STDataType StackTop(ST* ps);//取栈顶元素
bool STEmpty(ST* ps);//判断栈是否为空
int StackSize(ST* ps);//有多少数据
void STInit(ST* ps)//初始化
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}
void STDestroy(ST* ps)//销毁
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

void STPush(ST* ps, STDataType x)//插入
{
	assert(ps);
	if (ps->capacity == ps->top)//扩容
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newcapacity);
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;

}
void STPop(ST* ps)//删除
{
	assert(ps);
	assert(!STEmpty(ps));
	ps->top--;
}
STDataType StackTop(ST* ps)//取栈顶元素
{
	assert(ps);
	assert(!STEmpty(ps));
	return ps->a[ps->top - 1];
}

bool STEmpty(ST* ps)//判断栈是否为空
{
	return ps->top == 0;//为真返回true,为假返回false
}
int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}
typedef struct {
    ST pushst;
    ST popst;

} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));
    if(obj == NULL)
    {
        return NULL;
    }
    STInit(&obj->pushst);
    STInit(&obj->popst);
    return obj;

}

void myQueuePush(MyQueue* obj, int x) {
    STPush(&obj->pushst, x);
}

int myQueuePop(MyQueue* obj) {
    if(STEmpty(&obj->popst))
    {
        while(!STEmpty(&obj->pushst))
        {
            STPush(&obj->popst, StackTop(&obj->pushst));
            STPop(&obj->pushst);

        }

    }
    int front = StackTop(&obj->popst);
    STPop(&obj->popst);
    return front;
    
}

int myQueuePeek(MyQueue* obj) {
      if(STEmpty(&obj->popst))//如果pop为空,要倒数据
    {
        while(!STEmpty(&obj->pushst))
        {
            STPush(&obj->popst, StackTop(&obj->pushst));
            STPop(&obj->pushst);

        }

    }
    return StackTop(&obj->popst);

}

bool myQueueEmpty(MyQueue* obj) {
    return STEmpty(&obj->pushst) && STEmpty(&obj->popst);
}

void myQueueFree(MyQueue* obj) {
    STDestroy(&obj->pushst);
    STDestroy(&obj->popst);
    free(obj);

}

225. 用队列实现栈 - 力扣(LeetCode)

用两个队列实现栈,关键是要始终保持有一个队列是空的,这样方便后面倒数据,入队列的时候,给非空的队列里入数据,若都为空,就随便入一个,取栈顶数据时,由于队列是可以取队尾元素的,所以直接返回就行,删除栈顶元素时,先将非空队列的元素全都倒到空队列里去,再出队列就行。

代码实现如下:

typedef int QueueDataType;

typedef struct QueueNode
{
	QueueDataType data;
	struct QueueNode* next;
}QueueNode;

typedef struct Queue
{
	QueueNode* head;
	QueueNode* tail;
}Queue;

void QueueInit(Queue* pq);//初始化
void QueueDestroy(Queue* pq);//销毁
void QueuePop(Queue* pq);//弹出
void QueuePush(Queue* pq, QueueDataType x);//插入
QueueDataType QueueFront(Queue* pq);//队头数据
QueueDataType QueueBack(Queue* pq);//队尾数据
bool QueueEmpty(Queue* pq);//判空
int QueueSize(Queue* pq);//元素个数

void QueueInit(Queue* pq)//初始化
{
	assert(pq);
	pq->head = NULL;
	pq->tail = NULL;
}
void QueueDestroy(Queue* pq)//销毁
{
	assert(pq);
	QueueNode* cur = pq->head;
	while (cur)
	{
		QueueNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
}
	
void QueuePop(Queue* pq)//弹出
{
	assert(pq);
	assert(!QueueEmpty(pq));
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = NULL;
		pq->tail = NULL;
	}
	else
	{
		QueueNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}
void QueuePush(Queue* pq, QueueDataType x)//插入
{
	assert(pq);
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}
QueueDataType QueueFront(Queue* pq)//队头数据
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->head->data;
}
QueueDataType QueueBack(Queue* pq)//队尾数据
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->tail->data;
}
bool QueueEmpty(Queue* pq)//判空
{
	assert(pq);
	return pq->head == NULL;
}
int QueueSize(Queue* pq)//元素个数
{
	assert(pq);
	int size = 0;
	QueueNode* cur = pq->head;
	while (cur)
	{
		++size;
		cur = cur->next;
	}
	return size;

}
typedef struct {
    Queue q1;
    Queue q2;

} MyStack;


MyStack* myStackCreate() {
    MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
    if(obj == NULL)
    {
        return NULL;
    }
    QueueInit(&obj->q1);
    QueueInit(&obj->q2);
    return obj;

}

void myStackPush(MyStack* obj, int x) {
    if(!QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q1, x);

    }
    else
    {
        QueuePush(&obj->q2, x);
    }
    

}

int myStackPop(MyStack* obj) {
    Queue* emptyQ = &obj->q1;
    Queue* nonEmptyQ = &obj->q2;
    if(!QueueEmpty(&obj->q1))
    {
        emptyQ =  &obj->q2;
        nonEmptyQ = &obj->q1;
    }
    while(QueueSize(nonEmptyQ) > 1)
    {
        QueuePush(emptyQ, QueueFront(nonEmptyQ));
        QueuePop(nonEmptyQ);
    }
    int top = QueueFront(nonEmptyQ);
    QueuePop(nonEmptyQ);
    return top;

}

int myStackTop(MyStack* obj) {
     if(!QueueEmpty(&obj->q1))
    {
       return QueueBack(&obj->q1);

    }
    else
    {
       return QueueBack(&obj->q2);
    }

}

bool myStackEmpty(MyStack* obj) {
    return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);

}

void myStackFree(MyStack* obj) {
   QueueDestroy(&obj->q1);
   QueueDestroy(&obj->q2);
   free(obj);


}

622. 设计循环队列 - 力扣(LeetCode)

设计循环队列,队列的实现可以是链式的,但在此题中,最好用顺序表写,开辟的时候,有K个数字,多开辟一个空间,即K+1个空间,方便判断队列已满,用下标访问,用head表示队头,用tail表示队尾,开始时,head == tail表示该队列为空。若出现tail+1 == head,就表示队列已满,但要注意处理边界,即当tail+1 == k+1,tail = 0等,注意边界就行

代码实现如下:

typedef struct {
    int* a;
    int k;
    int head;
    int tail;

} MyCircularQueue;

//记得边界一定要控制一下!
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value);
bool myCircularQueueIsFull(MyCircularQueue* obj);

MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->a = (int*)malloc(sizeof(int)*(k+1));
    obj->head = obj->tail = 0;
    obj->k = k;
    return obj;

}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj))
    {
        return false;
    }
    else
    {
        obj->a[obj->tail] = value;
        obj->tail++;
    }
    if(obj->tail == obj->k+1)
    {
        obj->tail = 0;
    }
    return true;

}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return false;
    }
    obj->head++;
    if(obj->head == obj->k+1)
    {
        obj->head = 0;
    }
    return true;

}

int myCircularQueueFront(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    return obj->a[obj->head];
}

int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    {
        return -1;
    }
    
    int prev = obj->tail-1;
    if(obj->tail == 0)
    prev = obj->k;
    return obj->a[prev];
    
        
    


}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {

    return (obj->head == obj->tail);

}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    int next = obj->tail+1;
    if(next == obj->k+1)
    {
        next = 0;
    }
    return next == obj->head;
}

void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->a);
    free(obj);

}

水平有限,欢迎指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值