栈
栈,是一种特殊的线性结构,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出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;
}
}