『数据结构』栈和队列


栈,是一种特殊的线性结构,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则
在这里插入图片描述
栈的实现一般可以使用数组或链表实现,相对而言数组的结构更好一些。在数组的尾上插入删除数据的代价都比较小

栈接口实现


C语言实现


stack.h

#pragma once

typedef int ElementType;

/*---栈---*/
typedef struct Stack 
{
	ElementType* ele;
	size_t top;
	size_t capacity;
} Stack;

/*---初始化---*/
void stackInit(Stack* st);

/*---释放---*/
void stackDestory(Stack* st);

/*---压栈---*/
void stackPush(Stack* st, ElementType v);

/*---弹栈---*/
void stackPop(Stack* st);

/*---取出栈顶元素---*/
ElementType stackTop(const Stack* st);

/*---是否为空---*/
int stackEmpty(const Stack* st);

/*---栈元素数量---*/
size_t stackSize(const Stack* st);

stack.c

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "stack.h"

void stackInit(Stack* st)
{
	assert(st != NULL);
	st->capacity = 1;
	st->top = 0;
	st->ele = (ElementType*)malloc(sizeof(ElementType) * st->capacity);
	assert(st->ele != NULL);
}

void stackDestory(Stack* st)
{
	assert(st != NULL);
	free(st->ele);
	st->ele = NULL;
	st->top = 0;
	st->capacity = 0;
}

static void checkCapacity(Stack* st)
{
	if (st->top >= st->capacity)
	{
		st->capacity *= 2;
		st->ele = (ElementType*)realloc(st->ele,
			sizeof(ElementType) * st->capacity);
	}
}

void stackPush(Stack* st, ElementType v)
{
	assert(st != NULL);
	checkCapacity(st);
	++st->top;
	st->ele[st->top - 1] = v;
}

void stackPop(Stack* st)
{
	assert(st != NULL);
	--st->top;
}

ElementType stackTop(const Stack* st)
{
	assert(st != NULL);
	return st->ele[st->top - 1];
}

int stackEmpty(const Stack* st)
{
	assert(st != NULL);
	if (st->top == 0)
	{
		return 1;
	}
	return 0;
}

size_t stackSize(const Stack* st)
{
	return (size_t)st->top;
}

Java实现


public class MyStack {
    private int[] arr = null;
    private int size = 0;

    // 初始化
    public MyStack(int initCapacity) {
        this.arr = new int[initCapacity];
    }

    // 入栈
    public boolean push(int value) {
        if (this.size == this.arr.length) {
            return false;
        }

        this.arr[this.size] = value;
        ++this.size;
        return true;
    }

    // 出栈
    public Integer pop() {
        if (this.size == 0) {
            return null;
        }

        --this.size;
        return this.arr[this.size];
    }

    // 获取栈顶元素
    public Integer peek() {
        if (this.size == 0) {
            return null;
        }

        return this.arr[this.size - 1];
    }

    // 获取元素数量
    public int size() {
        return this.size;
    }

    // 栈是否为空
    public boolean isEmpty() {
        return this.size == 0;
    }
}

队列


队列,同样是一种特殊的线性结构,只允许在一端进行插入,在另一端进行删除数据操作队列遵循先进先出FIFO(First In First Out),进行插入操作的一端称为队尾,进行删除操作的一端称为队头
在这里插入图片描述
队列的实现可以使用数组和链表的结构实现使用链表实现更好,数组头上删数据不太方便(但是可以使用数组实现成循环队列的形式,效率还是很高的)。

接口实现(链表实现)


C语言版
queue.h

#pragma once

typedef int ElementType;

/*---队列结点---*/
typedef struct Node 
{
	ElementType value;
	struct Node* next;
} Node;

/*---队列---*/
typedef struct Queue 
{
	Node* front;
} Queue;

/*---初始化---*/
void queueInit(Queue* q);

/*---释放---*/
void queueDestory(Queue* q);

/*---入队---*/
void queuePush(Queue* q, ElementType v);

/*---出队---*/
void queuePop(Queue* q);

/*---队首元素---*/
ElementType queueFront(const Queue* q);

/*---队尾元素---*/
ElementType queueBack(const Queue* q);

/*---是否为空---*/
int queueEmpty(const Queue* q);

/*---队长---*/
size_t queueSize(const Queue* q);

queue.c

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "queue.h"

void queueInit(Queue* q)
{
	assert(q != NULL);
	q->front = NULL;
}

void queueDestory(Queue* q)
{
	assert(q != NULL);
	while (q->front != NULL)
	{
		Node* temp = q->front;
		q->front = q->front->next;
		free(temp);
		temp = NULL;
	}
}

static Node* createNode(ElementType v)
{
	Node* node = createNode(v);
	assert(node != NULL);
	node->value = v;
	return node;
}

void queuePush(Queue* q, ElementType v)
{
	assert(q != NULL); 
	Node* node = createNode(v);
	if (q->front == NULL)
	{
		node->next = NULL;
		q->front = node;
		return;
	}
	Node* cur = q->front;
	while (cur->next == NULL)
	{
		cur = cur->next;
	}
	node->next = NULL;
	cur->next = node;
}

void queuePop(Queue* q)
{
	assert(q != NULL);
	if (q->front == NULL)
	{
		return;
	}
	Node* temp = q->front;
	q->front = q->front->next;
	free(temp);
	temp = NULL;
}

ElementType queueFront(const Queue* q)
{
	assert(q != NULL);
	assert(q->front != NULL);
	return q->front->value;
}

ElementType queueBack(const Queue* q)
{
	assert(q != NULL);
	assert(q->front != NULL);
	Node* cur = q->front;
	while (cur->next != NULL)
	{
		cur = cur->next;
	}
	return cur->value;
}

int queueEmpty(const Queue* q)
{
	assert(q != NULL);
	if (q->front == NULL)
	{
		return 1;
	}
	return 0;
}

size_t queueSize(const Queue* q)
{
	assert(q != NULL);
	if (q->front == NULL)
	{
		return 0;
	}
	size_t size = 0;
	Node* cur = q->front;
	while (cur != NULL)
	{
		cur = cur->next;
		++size;
	}
	return size;
}

Java版

public class MyQueue {
    private ListNode head = null;
    private ListNode tail = null;
    private int size = 0;

    // 入队
    public void offer(int val) {
        ListNode newNode = new ListNode(val);

        ++this.size;

        if (this.head == null) {
            this.head = this.tail = newNode;
            return;
        }

        tail.next = newNode;
        tail = newNode;
    }

    // 出队
    public Integer poll() {
        if (this.size == 0) {
            return null;
        }

        --this.size;
        if (this.size == 0) {
            this.tail = null;
        }

        int ret = this.head.val;
        this.head = this.head.next;
        return ret;
    }

    // 取队首元素
    public Integer peek() {
        if (this.size == 0) {
            return null;
        }

        return this.head.val;
    }

    // 队列中元素个数
    public int size() {
        return this.size;
    }

    // 队列是否为空
    public boolean isEmpty() {
        return this.size == 0;
    }
}

class ListNode {
    public int val;
    public ListNode next = null;

    public ListNode(int val) {
        this.val = val;
    }
}

接口实现(数组实现循环队列)


C语言版
circular_queue.h

#pragma once

typedef int ElementType;

typedef struct CircularQueue{
	ElementType* cir_que;
	int front;
	int rear;
	int max_size;
} CircularQueue;

/* 初始化 */
void cqInit(CircularQueue* cq, int size);

/* 释放 */
void cqDestroy(CircularQueue* cq);

/* 判空 */
bool isEmpty(const CircularQueue* cq);

/* 队满 */
bool isFull(const CircularQueue* cq);

/* 入队 */
bool Push(CircularQueue* cq, ElementType val);

/* 出队 */
bool Pop(CircularQueue* cq);

/* 队首 */
ElementType Front(CircularQueue* cq);

/* 打印 */
void cqDisplay(const CircularQueue* cq);

circular_queue.c

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include "circular_queue.h"

void cqInit(CircularQueue* cq, int size){
	assert(cq != NULL);

	cq->front = 0;
	cq->rear = 0;
	cq->max_size = size;
	cq->cir_que = (ElementType*)malloc(sizeof(ElementType) 
			* cq->max_size);
	assert(cq->cir_que != NULL);
}

void cqDestroy(CircularQueue* cq){
	assert(cq != NULL);

	cq->front = 0;
	cq->rear = 0;
	cq->max_size = 0;
	free(cq->cir_que);
	cq->cir_que = NULL;
}

bool isEmpty(const CircularQueue* cq){
	assert(cq != NULL);

	return cq->front == cq->rear;
}

bool isFull(const CircularQueue* cq){
	assert(cq != NULL);

	return (cq->rear + 1) % cq->max_size == cq->front;
}

bool Push(CircularQueue* cq, ElementType val){
	assert(cq != NULL);

	if(isFull(cq)){
		return false;
	}
	cq->cir_que[cq->rear] = val;
	cq->rear = (cq->rear + 1) % cq->max_size;
	return true;
}

bool Pop(CircularQueue* cq){
	assert(cq != NULL);

	if(isEmpty(cq)){
		return false;
	}

	cq->front = (cq->front + 1) % cq->max_size;
	return true;
}

ElementType Front(CircularQueue* cq){
	assert(cq != NULL);

	if(!isEmpty(cq)){
		ElementType ret = cq->cir_que[cq->front];
		Pop(cq);
		return ret;
	}

	return -1;
}

void cqDisplay(const CircularQueue* cq){
	int i;

	printf("The circular queue is below: \n");
	for(i = cq->front; i < cq->rear; (++i) % cq->max_size){
		printf("%d ", cq->cir_que[i]);
	}
	printf("\n");
}

Java版

public class CycleQueue {
    private int[] arr;
    private int size = 0;
    private int front = 0;
    private int rear = 0;

    public CycleQueue(int initCapacity) {
        this.arr = new int[initCapacity];
    }

    // 入队
    public boolean offer(int val) {
        if (this.size == this.arr.length) {
            return false;
        }

        if (this.size != 0) {
            this.rear = (this.rear + 1) % this.arr.length;
        }
        this.arr[this.rear] = val;
        ++this.size;

        return true;
    }

    // 出队
    public Integer poll() {
        if (this.size == 0) {
            return null;
        }

        int ret = this.arr[this.front];
        if (this.front != this.rear) {
            this.front = (this.front + 1) % this.arr.length;
        }
        --this.size;

        return ret;
    }

    // 获取队首元素
    public Integer peek() {
        if (this.size == 0) {
            return null;
        }

        return this.arr[this.front];
    }

    // 获取队列中元素个数
    public int size() {
        return this.size;
    }

    // 判断队列是否为空
    public boolean isEmpty() {
        return this.size == 0;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值