数据结构----栈和队列

1.顺序表实现

在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
typedef int STDataType;

//顺序结构实现:实现一个更简单的顺序表
//可以调用顺序表接口来实现
typedef struct stack
{
	STDataType* _data;
	int _size;
	int _capacity;
}stack;

void initStack(stack* st)
{
	//空栈
	if (st == NULL)
		return;
	st->_data = NULL;
	st->_size = st->_capacity = 0;
}
void checkCapacity(stack* st)
{
	if (st->_size == st->_capacity)
	{
		int newCap = st->_capacity == 0 ? 1 : 2 * st->_capacity;
		st->_data = (STDataType*)realloc(st->_data,sizeof(STDataType)*newCap);
		st->_capacity = newCap;
	
	}
}
void stackPush(stack* st, STDataType val)//入栈
{
	//尾插
	if (st == NULL)
		return;
	checkCapacity(st);
	st->_data[st->_size++] = val;
}
void stackPop(stack* st)
{
	//尾删
	if (st == NULL || st->_size == 0)
		return;
	--st->_size;

}
int stackSize(stack* st)
{
	if (st == NULL)
		return 0;
	return st->_size;
}
int stackEmpty(stack* st)
{
	if (st == NULL || st->_size)
		return 1;
	else
		return 0;
	
}
STDataType stackTop(stack* st)
{
	return st->_data[st->_size - 1];
}



void test()
{
	stack st;
	initStack(&st);
}
int main()
{
	test();
	return 0;
}

2.队列

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出
FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头

在这里插入图片描述
不带头非循环单向(头尾指针)
入队:尾插
出队:头删

#include<stdio.h>
#include<stdlib.h>

//队列:带有尾指针的单链表

typedef int QDaTaType;
typedef struct QNode
{
	QDaTaType _data;
	struct QNode* _next;
};

typedef struct Queue
{
	//头尾指针
	struct QNode* _head;
	struct QNode* _tail;
	int _size;
}Queue;

void initQueue(Queue* q)
{
	//空队列
	if (q == NULL)
		return;
	q->_head = q->_tail = NULL;
	q->_size = 0;
}

struct QNode* creatNode(QDaTaType val)
{
	struct QNode* node = (struct QNode*)malloc(sizeof(struct QNode));
	node->_data = val;
	node->_next = NULL;
}
void queuePush(Queue* q, QDaTaType val)//入队
{	
	if (q == NULL)
		return;
	//尾插
	struct QNode* node = creatNode(val);
	//第一个节点
	if (q->_head == NULL)
		q->_head = q->_tail = node;
	else
	{
		q->_tail->_next = node;
		q->_tail = node;
	}
	++q->_size;
}

void queuePop(Queue* q)//出队
{
	if (q == NULL || q->_head == NULL)
		return;
	//头删
	struct QNode *next = q->_head->_next;
	free(q->_head);
	q->_head = next;
	if (q->_head == NULL)
		q->_tail = NULL;//空队列
	--q->_size;
}

QDaTaType queueFront(Queue* q)
{
	return q->_head->_data;
}

QDaTaType queueBack(Queue* q)
{
	return q->_tail->_data;
}

int queueEmpty(Queue* q)
{
	return q->_head == NULL; 
}

int queueSize(Queue* q)
{
	if (q == NULL)
		return 0;
	return q->_size;
	//遍历
}
void test()
{
	struct Queue q;
	initQueue(&q);
}

栈和队列面试题

1. 括号匹配问题。

bool isValid(char * s)
{
    //用栈实现
    int map[3][2]={{'(',')'},{'[',']'},{'{','}'}};
    int n=strlen(s);
    int stk[n+1];
    int top=0;
    if(n%2==1)
    return false;
    while(*s)
    {
        int flag=0;
        //左括号:入栈
        for(int i=0;i<3;++i)
        {
            if(*s==map[i][0])
            {
                stk[top++]=*s;
                //判断下一个
                ++s;
                flag=1;
                break;
            }
        }
        //右括号
        if(flag==0)
        {
            if(top==0)
            return false;//空栈无法取出元素,故必须要判断
            //取出栈顶元素
        int topChar=stk[top-1];
            --top;
            //找出当前字符*s对应的左括号
            for(int i=0;i<3;++i)
            {
                if(map[i][1]==*s)
                {
                    if(topChar==map[i][0])
                    {
                        //判断下一个字符
                        ++s;
                        break;
                    }
                    else
                    return false;
                }
            }
        }
bool isValid(char * s)
{
   char arr[128]={0};
    arr[')']='(';
    arr[']']='[';
    arr['}']='{';//右边映射左边
    int n=strlen(s);
    int stk[n+1];
    int top=0;
    while(*s)
    {
        int flag=0;
        if(*s=='('||*s=='['||*s=='{')
        {
            stk[top++]=*s;
            ++s;
            flag=1;
        }
        //右括号
        if(flag==0)
        {
            
            if(top==0)
            return false;
            //取出栈顶
            char topChar=stk[top-1];
            --top;
            if(arr[*s]==topChar)
            {
            ++s;
            }
            else
            return false;

        }
    }
    return top==0;
}

2. 用队列实现栈。

一个队列的做法

 #include<stdio.h>
#include<stdlib.h>

//队列:带有尾指针的单链表

typedef int QDaTaType;
typedef struct QNode
{
	QDaTaType _data;
	struct QNode* _next;
}QNode;

typedef struct Queue
{
	//头尾指针
	struct QNode* _head;
	struct QNode* _tail;
	int _size;
}Queue;

void initQueue(Queue* q)
{
	//空队列
	if (q == NULL)
		return;
	q->_head = q->_tail = NULL;
	q->_size = 0;
}

struct QNode* creatNode(QDaTaType val)
{
	struct QNode* node = (struct QNode*)malloc(sizeof(struct QNode));
	node->_data = val;
	node->_next = NULL;
    return node;
}
void queuePush(Queue* q, QDaTaType val)//入队
{	
	if (q == NULL)
		return;
	//尾插
	struct QNode* node = creatNode(val);
	//第一个节点
	if (q->_head == NULL)
		q->_head = q->_tail = node;
	else
	{
		q->_tail->_next = node;
		q->_tail = node;
	}
	++q->_size;
}

void queuePop(Queue* q)//出队
{
	if (q == NULL || q->_head == NULL)
		return;
	//头删
	struct QNode *next = q->_head->_next;
	free(q->_head);
	q->_head = next;
	if (q->_head == NULL)
		q->_tail = NULL;//空队列
	--q->_size;
}

QDaTaType queueFront(Queue* q)
{
	return q->_head->_data;
}

QDaTaType queueBack(Queue* q)
{
	return q->_tail->_data;
}

int queueEmpty(Queue* q)
{
	return q->_head == NULL; 
}

int queueSize(Queue* q)
{
	if (q == NULL)
		return 0;
	return q->_size;
	//遍历
}

void queueDestroy(Queue* q)
{
    QNode* cur=q->_head;
    while(cur)
    {
        QNode* next=cur->_next;
        free(cur);
        cur=next;
    }
    q->_head=q->_tail=NULL;
}


typedef struct {
    //队列成员
    struct Queue q;//定义一个q的队列

} MyStack;

/** Initialize your data structure here. */

MyStack* myStackCreate() {
    //动态创建
    MyStack* pst=(MyStack*)malloc(sizeof(MyStack));//栈上的结构体变量
    initQueue(&pst->q);//结构体变量的成员
    return pst;
}

/** Push element x onto stack. */
void myStackPush(MyStack* obj, int x) {
   queuePush(&obj->q,x);

}

/** Removes the element on top of the stack and returns that element. */
//一个队列的做法
int myStackPop(MyStack* obj) {//出队
  
    int n=queueSize(&obj->q);
    while(n>1)
    {
        //出队,入队
        int front=queueFront(&obj->q);//队头元素
        queuePop(&obj->q);
        queuePush(&obj->q,front);
        --n;
    }
    int top=queueFront(&obj->q);
    queuePop(&obj->q);
    return top;
}

/** Get the top element. */
int myStackTop(MyStack* obj) {
    return queueBack(&obj->q);
}

/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj) {
    return queueEmpty(&obj->q);
}

void myStackFree(MyStack* obj) {
    queueDestroy(&obj->q);
    free(obj);
}


两个队列的做法

typedef struct {
    struct Queue q1;
    struct Queue q2;

} MyStack;

/** Initialize your data structure here. */

MyStack* myStackCreate() {
    MyStack* pst=(MyStack*)malloc(sizeof(MyStack));
    initQueue(&pst->q1);
    initQueue(&pst->q2);
    return pst;
}

/** Push element x onto stack. */
void myStackPush(MyStack* obj, int x) {
    //非空队列入栈
    if(!queueEmpty(&obj->q1))
        queuePush(&obj->q1,x);
    else
        queuePush(&obj->q2,x);

}

/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack* obj) {
    int top;
    if(!queueEmpty(&obj->q1))
    {
        int n=queueSize(&obj->q1);
        while(n>1)
        {
            //出队,入队
            int front=queueFront(&obj->q1);
            queuePop(&obj->q1);
            queuePush(&obj->q2,front);
            --n;

        }
         top=queueFront(&obj->q1);
        queuePop(&obj->q1);
    }
    else
    {
        int n=queueSize(&obj->q2);
        while(n>1)
        {
            int front=queueFront(&obj->q2);
            queuePop(&obj->q2);
            queuePush(&obj->q1,front);
            --n;
        }
        top=queueFront(&obj->q2);
        queuePop(&obj->q2);
    }
    return top;
}

/** Get the top element. */
int myStackTop(MyStack* obj) {//栈顶元素
    if(!queueEmpty(&obj->q1))
        return queueBack(&obj->q1);
    else
        return queueBack(&obj->q2);
}

/** 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(obj);
}

3. 用栈实现队列

在这里插入图片描述

4. 设计循环队列.

typedef struct {
    //对头元素的位置
    int _front;
    //队尾元素的下一个位置
    int _rear;
    //队列的容量
    int _k;
    //存放元素空间的首地址
    int * _data;
} MyCircularQueue;


MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* cq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    cq->_data=(int*)malloc(sizeof(int)*(k+1));
    cq->_k=k;
    cq->_front=cq->_rear=0;
    return cq; 
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->_front==obj->_rear; 
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
    //rear+1  %  空间的长度
    return (obj->_rear+1)%(obj->_k+1)==obj->_front;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
   //队列已满,不能入队
   if(myCircularQueueIsFull(obj))
    return false;
   //队尾入队
    obj->_data[obj->_rear++]=value;
    //判断队尾是否越界[0,k]
    if(obj->_rear>obj->_k)
    obj->_rear=0;
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    //队列为空,出队失败
    if(myCircularQueueIsEmpty(obj))
    return false;
    //队头出队
    obj->_front++;

    //判断队头是否越界
    if(obj->_front>obj->_k)
    obj->_front=0;
    return true;
}

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

int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    return -1;
    if(obj->_rear!=0)
        return obj->_data[obj->_rear-1];
    else
    //rear为0,队尾元素在数组的末尾
        return obj->_data[obj->_k];

}

void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->_data);//队列当中数组的空间
    free(obj);//队列空间
}


//给有效元素的做法fa


```c

typedef struct {
    //对头元素的位置
    int _front;
    //队尾元素的下一个位置
    int _rear;
    //队列的容量
    int _k;
    //存放元素空间的首地址
    int * _data;

    int _size;//有效元素的个数
} MyCircularQueue;


MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* cq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    cq->_data=(int*)malloc(sizeof(int)*k);
    cq->_k=k;
    cq->_front=cq->_rear=0;
    cq->_size=0;
    return cq; 
}

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    return obj->_size==0;
}

bool myCircularQueueIsFull(MyCircularQueue* obj) {
  
    return obj->_size==obj->_k;
}

bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
   //队列已满,不能入队
   if(myCircularQueueIsFull(obj))
    return false;
   //队尾入队
    obj->_data[obj->_rear++]=value;
    //判断队尾是否越界[0,k)
    if(obj->_rear>=obj->_k)
    obj->_rear=0;

    obj->_size++;
    return true;
}

bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    //队列为空,出队失败
    if(myCircularQueueIsEmpty(obj))
    return false;
    //队头出队
    obj->_front++;

    //判断队头是否越界
    if(obj->_front>=obj->_k)
    obj->_front=0;

    obj->_size--;
    return true;
}

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

int myCircularQueueRear(MyCircularQueue* obj) {
    if(myCircularQueueIsEmpty(obj))
    return -1;
    if(obj->_rear!=0)
        return obj->_data[obj->_rear-1];
    else
    //rear为0,队尾元素在数组的末尾
        return obj->_data[obj->_k-1];

}

void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->_data);//队列当中数组的空间
    free(obj);//队列空间
}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值