队列 栈自我总结

最近重新学习了一遍队列和栈,让我对于这两个结构有了深刻的认知。

栈是一个先进后出的结构,可以通过数组或者链表来实现。

一个支持动态增长的栈包含这些功能。

// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* _a;
	int _top;		// 栈顶
	int _capacity;  // 容量 
}Stack;
// 初始化栈 
void StackInit(Stack* ps); 
// 入栈 
void StackPush(Stack* ps, STDataType data); 
// 出栈 
void StackPop(Stack* ps); 
// 获取栈顶元素 
STDataType StackTop(Stack* ps); 
// 获取栈中有效元素个数 
int StackSize(Stack* ps); 
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* ps); 
// 销毁栈 
void StackDestroy(Stack* ps); 

我发现需要建立动态的栈时,新的指针是通过realloc进行的。

STDataType* tmp =(STDataType*) realloc(ps->a, sizeof(STDataType) * newCapacity);

每当栈里面的Capacity满了之后需要进行扩容。

int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;

 以此来实现栈的动态扩容。

以下是完整代码:

void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}
void StackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}
void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		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 StackPop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	ps->top--;
}
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	return ps->a[ps->top-1];
}
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}
int STackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------队列 是一个先进先出的结构,可以通过链表和数组来实现其功能。

// 链式结构:表示队列 
typedef struct QListNode 
{ 
	struct QListNode* _next; 
	QDataType _data; 
}QNode; 
 
// 队列的结构 
typedef struct Queue 
{ 
	QNode* _front; 
	QNode* _rear; 
}Queue; 
 
// 初始化队列 
void QueueInit(Queue* q); 
// 队尾入队列 
void QueuePush(Queue* q, QDataType data); 
// 队头出队列 
void QueuePop(Queue* q); 
// 获取队列头部元素 
QDataType QueueFront(Queue* q); 
// 获取队列队尾元素 
QDataType QueueBack(Queue* q); 
// 获取队列中有效元素个数 
int QueueSize(Queue* q); 
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q); 
// 销毁队列 
void QueueDestroy(Queue* q);
 
#define _CRT_SECURE_NO_WARNINGS 1
#include "Queue.h"

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
}
void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur;
		free(cur);
		cur = next;
	}
}
void QueuePush(Queue* pq, QDatatype x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		printf("malloc fail\n");
		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;
	}
}
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	if (pq->head->next = NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}
QDatatype QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}
QDatatype QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	
	return pq->tail->data;
}
bool QueueEmpty(Queue* pq)
{
	return pq->head == NULL;
}
int QueueSize(Queue* pq)
{
	int sum = 0;
	QNode* cur = pq->head;
	while (cur)
	{
		++sum;
		cur = cur->next;
	}
	return sum;
}

 其实可用队列来实现栈,用栈来实现队列。

这是栈实现队列:

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}
void StackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}
void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		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 StackPop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	ps->top--;
}
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	return ps->a[ps->top-1];
}

int STackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}




typedef struct {
    ST pushst;
    ST popst;
} MyQueue;


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

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

int myQueuePop(MyQueue* obj) {
    if(StackEmpty(&obj->popst))
    {
        while(!StackEmpty(&obj->pushst))
        {
            StackPush(&obj->popst,StackTop(&obj->pushst));
            StackPop(&obj->pushst);
        }
    }
    int front=StackTop(&obj->popst);
    StackPop(&obj->popst);
    return front;
}

int myQueuePeek(MyQueue* obj) {
if(StackEmpty(&obj->popst))
    {
        while(!StackEmpty(&obj->pushst))
        {
            StackPush(&obj->popst,StackTop(&obj->pushst));
            StackPop(&obj->pushst);
        }
    }

    return StackTop(&obj->popst);
}

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

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

/**
 * Your MyQueue struct will be instantiated and called as such:
 * MyQueue* obj = myQueueCreate();
 * myQueuePush(obj, x);
 
 * int param_2 = myQueuePop(obj);
 
 * int param_3 = myQueuePeek(obj);
 
 * bool param_4 = myQueueEmpty(obj);
 
 * myQueueFree(obj);
*/

 这是队列实现栈


typedef int QDatatype;


typedef struct QueueNode
{
    struct QueueNode* next;
    QDatatype data;
}QNode;


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



void QueueInit(Queue* pq)
{
    assert(pq);
    pq->head = pq->tail = NULL;
    
}
bool QueueEmpty(Queue* pq)
{
    assert(pq);
    return pq->head == NULL;
}
void QueueDestroy(Queue* pq)
{
    assert(pq);
    QNode * cur;
    cur = pq->head;
    while (cur)
    {
        QNode*next = cur->next;
        free(cur);
        cur = next;
    }
    pq->head = pq->tail = NULL;
}
void QueuePush(Queue* pq, QDatatype x)
{
    assert(pq);
    QNode* newnode = (QNode*)malloc(sizeof(QNode));
    if (newnode == NULL)
    {
        printf("malloc fail\n");
        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;
    }
}
void QueuePop(Queue* pq)
{
    assert(pq);
    assert(!QueueEmpty(pq));
    //只剩一个节点,避免tail变成野指针
    if (pq->head->next == NULL)
    {
        free(pq->head);
        pq->head = pq->tail = NULL;
    }
    else
    {
        QNode* next = pq->head->next;
        free(pq->head);
        pq->head = next;
    }


}
QDatatype QueueFront(Queue* pq)
{
    assert(pq);
    assert(!QueueEmpty(pq));
    return pq->head->data;
}
QDatatype QueueBack(Queue* pq)
{
    assert(pq);
    assert(!QueueEmpty(pq));
    
    return pq->tail->data;
}


int QueueSize(Queue* pq)
{
    assert(pq);
    QNode* cur = pq->head;
    int size = 0;
    while (cur)
    {
        ++size;
        cur = cur->next;
    }
    return size;
}//也可以在结构体中加size。



typedef struct {
    Queue q1;
    Queue q2;
} MyStack;



MyStack* myStackCreate() {
     MyStack*obj=(MyStack*)malloc(sizeof(MyStack));
     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*nonEmpty=&obj->q2;
    if(!QueueEmpty(&obj->q1))
    {
        emptyQ=&obj->q2;
        nonEmpty=&obj->q1;
    }
    while(QueueSize(nonEmpty)>1)
    {
        QueuePush(emptyQ,QueueFront(nonEmpty));
        QueuePop(nonEmpty);
    }
    int top=QueueFront(nonEmpty);
        QueuePop(nonEmpty);
        return top;
}


int myStackTop(MyStack* obj) {
    Queue*emptyQ=&obj->q1;
    Queue*nonEmpty=&obj->q2;
    if(!QueueEmpty(&obj->q1))
    {
        emptyQ=&obj->q2;
        nonEmpty=&obj->q1;
    }
    return QueueBack(nonEmpty);
}


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


void myStackFree(MyStack* obj) {
    QueueDestroy(&obj->q1);
    QueueDestroy(&obj->q2);
    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);
*/

 最后队列还有一种特殊的形态,为循环队列

这是循环队列

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


} MyCircularQueue;



MyCircularQueue* myCircularQueueCreate(int k) {
       MyCircularQueue*obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
       obj->a=malloc(sizeof(int)*(k+1));
       obj->head=0;
       obj->tail=0;
       obj->k=k;
       return obj;
}
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;
}


bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(myCircularQueueIsFull(obj))
        return false;
    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];
}




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


/**
 * Your MyCircularQueue struct will be instantiated and called as such:
 * MyCircularQueue* obj = myCircularQueueCreate(k);
 * bool param_1 = myCircularQueueEnQueue(obj, value);
 
 * bool param_2 = myCircularQueueDeQueue(obj);
 
 * int param_3 = myCircularQueueFront(obj);
 
 * int param_4 = myCircularQueueRear(obj);
 
 * bool param_5 = myCircularQueueIsEmpty(obj);
 
 * bool param_6 = myCircularQueueIsFull(obj);
 
 * myCircularQueueFree(obj);
*/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值