栈和队列的概念与实现

栈的概念及结构

栈是一种特殊的线性表,只允许在固定的一端进行插入删除操作,进行数据的插入删除操作的一端被称为栈顶,另一端被称为栈底,栈中的数据遵循后进先出的原则,栈的插入操作叫做压栈/进栈/入栈,入数据在栈顶,栈的删除操作称为出栈,出数据也在栈顶。分别有链式栈和数组栈。

栈的实现(数组栈)

栈的结构

typedef int valuetype;
typedef struct stack
{
	valuetype* arr;
	int top;
	int capacity;
}stack;

初始化

void Init(stack* pst)
{
	assert(pst);
	pst->arr=(valuetype*)malloc(sizeof(valuetype)*4);
	if(pst->arr==NULL)
	{
		perror("malloc fail");
		return;
	}
	pst->top=0;
	pst->capacity=4;
}

销毁

void destroy(stack* pst)
{
	free(pst->arr);
}

删除栈顶元素

void pop(stack* pst)
{
	assert(pst);
	assert(!isempty(pst));
	pst->top--;
}

插入元素

void push(stack* pst,valuetype x)
{
	if(isfull(pst))
	{
		pst->capacity*=2;//若刚开始容量给的是0则这个地方还要进行一个三目判断
		valuetype* tmp=(valuetype*)realloc(pst->arr,pst->capacity*sizeof(valuetype));
		if(tmp==NULL)
		{
			perror("realloc fail");
			return;
		}
		pst->arr=tmp;
	}
	pst->arr[pst->top]=x;
	pst->top++;
}

判空

bool isempty(stack* pst)
{
	assert(pst);
	if(pst->top==0)
		return true;
	return false;
}

判满

bool isfull(stack* pst)
{
	if(pst->top==pst->capacity)
		return true;
	return false;
}

栈顶元素

valuetype top(stack* pst)
{
	assert(pst);
	assert(pst->top);
	return pst->arr[pst->top-1];
}//为什么要有这个函数,因为使用的人并不知道你初始化是哪种初始化,还得回去看你的初始化源码

数据个数

int size(stack* pst)
{
	assert(pst);
	return pst->size;
}

队列

队列的概念与结构

只允许在一段进行插入操作,在另一端进行删除操作,进行插入数据的一端叫做队尾,删除数据的一端称为队头,插入数据称为入队,删除数据称为出队。

队列的实现

队列的结构

typedef int valuetype
typedef struct queuenode
{
	struct queue next;
	valuetype data;
}node;
typedef struct queue
{
	node* phead;
	node* ptail;
	int size;
}queue;

初始化

void Init(queue* pq)
{
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

销毁

void destroy(queue* pq)
{
	node* cur = pq->phead;
	while (cur != NULL)
	{
		node* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
}

插入

void push(queue* pq, valuetype x)
{
	node* newnode = (node*)malloc(sizeof(node));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}
	newnode->next = NULL;
	newnode->data = x;
	if (pq->phead == NULL&&pq->ptail == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		newnode->next = NULL;
		newnode->data = x;
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	pq->size++;
}

删除

void erase(queue* pq)
{
	assert(pq);
	assert(pq->phead!=NULL);
	node* cur = pq->phead;
	node* next = cur->next;
	free(cur);
	pq->phead = next;
	if (pq->phead == NULL)
	{
		pq->ptail = NULL;
	}
	pq->size--;
}

返回队头元素

valuetype returnfront(queue* pq)
{
	assert(pq);
	assert(pq->phead);
	return pq->phead->data;
}

判断队列是否为空

bool isempty(queue* pq)
{
	if (pq->size == 0)
		return true;
	return false;
}

返回队尾元素

valuetype returnback(queue* pq)
{
	assert(pq);
	assert(pq->ptail); 
	return pq->ptail->data;
}

加深印象推荐题目

用队列实现栈

https://leetcode.cn/problems/implement-stack-using-queues/

typedef int valuetype;
typedef struct queuenode
{
	struct queuenode* next;
	valuetype data;
}node;
typedef struct queue
{
	node* phead;
	node* ptail;
	int size;
}queue;


void Init(queue* pq)
{
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

void destroy(queue* pq)
{
	node* cur = pq->phead;
	while (cur != NULL)
	{
		node* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->phead = pq->ptail = NULL;
}

void push(queue* pq, valuetype x)
{
	node* newnode = (node*)malloc(sizeof(node));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}
	newnode->next = NULL;
	newnode->data = x;
	if (pq->phead == NULL&&pq->ptail == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		newnode->next = NULL;
		newnode->data = x;
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	pq->size++;
}

void erase(queue* pq)
{
	assert(pq);
	assert(pq->phead!=NULL);
	node* cur = pq->phead;
	node* next = cur->next;
	free(cur);
	pq->phead = next;
	if (pq->phead == NULL)
	{
		pq->ptail = NULL;
	}
	pq->size--;
}

valuetype returnfront(queue* pq)
{
	assert(pq);
	assert(pq->phead);
	return pq->phead->data;
}

bool isempty(queue* pq)
{
	if (pq->size == 0)
		return true;
	return false;
}


valuetype returnback(queue* pq)
{
	assert(pq);
	assert(pq->ptail); 
	return pq->ptail->data;
}


typedef struct {
    queue* a1;
    queue* a2;
} MyStack;


MyStack* myStackCreate() {
    MyStack* obj=(MyStack*)malloc(sizeof(MyStack));
    if(obj==NULL)
    {
        perror("malloc fail");
        return NULL;
    }
    obj->a1=(queue*)malloc(sizeof(queue));
    obj->a2=(queue*)malloc(sizeof(queue));
    Init(obj->a1);
    Init(obj->a2);
    return obj;
}

void myStackPush(MyStack* obj, int x) {
    if(isempty(obj->a1))
    {
        push(obj->a2,x);
    }
    else if(isempty(obj->a2))
    {
        push(obj->a1,x);
    }
}

int myStackPop(MyStack* obj) {
    valuetype x=0;
    if(isempty(obj->a1))
    {
        while(obj->a2->size!=1)
        {
            valuetype tmp=returnfront(obj->a2);
            erase(obj->a2);
            push(obj->a1,tmp);
        }
        x=returnfront(obj->a2);
        erase(obj->a2);
    }
    else if(isempty(obj->a2))
    {
        while(obj->a1->size!=1)
        {
            valuetype tmp=returnfront(obj->a1);
            erase(obj->a1);
            push(obj->a2,tmp);
        }
        x=returnfront(obj->a1);
        erase(obj->a1);
    }
    return x;
}

int myStackTop(MyStack* obj) {
     valuetype x=0;
    if(isempty(obj->a1))
    {
        while(obj->a2->size)
        {
            valuetype tmp=returnfront(obj->a2);
            erase(obj->a2);
            push(obj->a1,tmp);
            x=tmp;
        }
    }
    else if(isempty(obj->a2))
    {
        while(obj->a1->size!=0)
        {
            valuetype tmp=returnfront(obj->a1);
            erase(obj->a1);
            push(obj->a2,tmp);
            x=tmp;
        }
    }
    return x;
}

bool myStackEmpty(MyStack* obj) {
    if(((!isempty(obj->a1))&&(!isempty(obj->a2)))
    ||(isempty(obj->a1)&&(!isempty(obj->a2)))
    ||((!isempty(obj->a1))&&isempty(obj->a2)))
        return false;
    return true;
}

void myStackFree(MyStack* obj) {
    free(obj->a1);
    free(obj->a2);
    free(obj);
}

用栈实现队列

https://leetcode.cn/problems/implement-queue-using-stacks/

typedef int valuetype;
typedef struct stack
{
	valuetype* arr;
	int top;
	int capacity;
}stack;

void Init(stack* pst)
{
	assert(pst);
	pst->arr=(valuetype*)malloc(sizeof(valuetype)*4);
	if(pst->arr==NULL)
	{
		perror("malloc fail");
		return;
	}
	pst->top=0;
	pst->capacity=4;
}


bool isempty(stack* pst)
{
	assert(pst);
	if(pst->top==0)
		return true;
	return false;
}

bool isfull(stack* pst)
{
	if(pst->top==pst->capacity)
		return true;
	return false;
}

valuetype top(stack* pst)
{
	assert(pst);
	assert(pst->top);
	return pst->arr[pst->top-1];
}//为什么要有这个函数,因为使用的人并不知道你初始化是哪种初始化,还得回去看你的初始化源码


void pop(stack* pst)
{
	assert(pst);
	assert(!isempty(pst));
	pst->top--;
}

void push(stack* pst,valuetype x)
{
	if(isfull(pst))
	{
		pst->capacity*=2;//若刚开始容量给的是0则这个地方还要进行一个三目判断
		valuetype* tmp=(valuetype*)realloc(pst->arr,pst->capacity*sizeof(valuetype));
		if(tmp==NULL)
		{
			perror("realloc fail");
			return;
		}
		pst->arr=tmp;
	}
	pst->arr[pst->top]=x;
	pst->top++;
}



void destroy(stack* pst)
{
	free(pst->arr);
}


typedef struct {
    stack* a1;
    stack* a2;
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
    obj->a1=(stack*)malloc(sizeof(stack));
    obj->a2=(stack*)malloc(sizeof(stack));
    Init(obj->a1);
    Init(obj->a2);
    return obj;
}

void myQueuePush(MyQueue* obj, int x) {
    push(obj->a1,x);
}

int myQueuePop(MyQueue* obj) {
    if(isempty(obj->a2))
    {
        while(!isempty(obj->a1))
        {
            valuetype tmp=obj->a1->arr[obj->a1->top-1];
            pop(obj->a1);
            push(obj->a2,tmp);
        }
    }
    valuetype tmp=obj->a2->arr[obj->a2->top-1];
    pop(obj->a2);
    return tmp;
}

int myQueuePeek(MyQueue* obj) {
    if(isempty(obj->a2))
    {
        while(!isempty(obj->a1))
        {
            valuetype tmp=obj->a1->arr[obj->a1->top-1];
            pop(obj->a1);
            push(obj->a2,tmp);
        }
    }
    return obj->a2->arr[obj->a2->top-1];
}

bool myQueueEmpty(MyQueue* obj) {
    if((isempty(obj->a1)&&!isempty(obj->a2))||(!isempty(obj->a1)&&isempty(obj->a2))||((!isempty(obj->a1))&&(!isempty(obj->a2))))
    {
        return false;
    }
    return true;
}

void myQueueFree(MyQueue* obj) {
    free(obj->a1);
    free(obj->a2);
    free(obj);
}

设计循环队列

https://leetcode.cn/problems/design-circular-queue/
这一题有两种解法,下面只实现链表的解法

typedef struct qnode
{
    struct qnode* next;
    int data;
}node;


typedef struct {
    node* phead;
    node* ptail;
} MyCircularQueue;


MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    obj->phead=obj->ptail=NULL;
    node* head=(node*)malloc(sizeof(node));
    head->next=head;
    head->data=-1;
    obj->phead=obj->ptail=head;
    for(int i=0;i<k;i++)
    {
        node* tmp=(node*)malloc(sizeof(node));
        tmp->next=obj->phead;
        tmp->data=-1;
        obj->ptail->next=tmp;
        obj->ptail=tmp;
    }
    obj->ptail=obj->phead;
    return obj;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(obj->phead==obj->ptail->next)
    {
        return false;
    }
    node* cur=obj->ptail->next;
    cur->data=value;
    obj->ptail=cur;
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    if(obj->phead==obj->ptail)
        return false;
    obj->phead=obj->phead->next;
    return true;
}

int myCircularQueueFront(MyCircularQueue* obj) {
    if(obj->phead==obj->ptail)
        return -1;
    return obj->phead->next->data;
}

int myCircularQueueRear(MyCircularQueue* obj) {
    if(obj->phead==obj->ptail)
        return -1;
    return obj->ptail->data;
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    if(obj->phead==obj->ptail)
        return true;
    return false;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    if(obj->ptail->next==obj->phead)
        return true;
    return false;
}

void myCircularQueueFree(MyCircularQueue* obj) {
    node* cur=obj->phead;
    node* next=cur->next;
    while(cur->next!=obj->phead)
    {
        free(cur);
        cur=next;
        next=cur->next;
    }
    free(cur);
    free(obj);
}
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值