如何用数组实现队列和栈?

【栈】
栈的特性是先进后出。
pop:把栈顶元素弹出栈
push:把元素压入栈
peek:得到栈顶元素的值

/*
首先建立一个N大小的数组arr[N],表示这个栈最多有N个元素
用size表示栈中元素的个数,初始size = 0,且表示下一个压栈元素的位置
*/
void push(int num){
	if(size >= N ){
		cout << "栈满" << endl;
		return;
	}
	arr[size++] = num;
}

int pop(){
	if(size == 0){
		cout << "栈空" << endl;
		return;
	}
	return arr[--size];
	//peek就改成 return arr[size-1];
}

【队列】
队列的特性是先进先出
依旧是建立一个数组,N代表容量, size代表当前元素个数
不同的是,压入队列和弹出队列用不同的指针来指向,这里用end表示下一个压入队列的元素位置,begin表示弹出队列的位置,用size约束end和begin,如果size为0,则begin失效,如果size=N,则end失效;end和begin之间互不影响。如果end指向N且size!=N,则循环end,指向最开始的位置、begin一样
(begin转圈追end都追不上)

void enq(int num){
	if(size==N)	return;
	end %= N;
	arr[end++] = num;
	size++;
}
int deq(){
	if(size==0)	return;
	begin %= N;
	size--;
	return arr[begin++];
}
<think> 我们使用数组实现队列。首先,是一种后进先出(LIFO)的数据结构,而队列是一种先进先出(FIFO)的数据结构。 对于,我们需要一个数组一个指向顶的指针(或索引)。主要操作有:入(push)、出(pop)、查看顶元素(peek)等。 对于队列,我们可以使用数组两个指针(或索引)分别指向队头队尾。主要操作有:入队(enqueue)、出队(dequeue)、查看队头元素(front)等。 注意:在使用数组实现队列时,我们通常会使用循环队列来避免数据搬移,提高效率。 下面分别给出实现: 1. (Stack)的数组实现: 我们需要定义: - 一个固定大小的数组(假设最大容量为MAX) - 一个整型变量top,表示顶的索引 操作: - 初始化:top = -1 - 入:先检查是否已满(top == MAX-1),不满则top加1,然后在top位置放入元素 - 出:先检查是否为空(top == -1),不空则取出top位置的元素,然后top减1 - 查看顶:直接返回top位置的元素(不改变top) 2. 队列(Queue)的数组实现(循环队列): 我们需要定义: - 一个固定大小的数组(假设最大容量为MAX) - 两个整型变量:front(队头)rear(队尾) - 通常,我们让front指向队列第一个元素,rear指向队列最后一个元素的下一个位置(这样可以利用一个空位来区分队空队满) 操作: - 初始化:front = 0, rear = 0 - 入队:先检查队列是否已满((rear+1)%MAX == front),不满则将元素放入rear位置,然后rear = (rear+1)%MAX - 出队:先检查队列是否为空(front == rear),不空则取出front位置的元素,然后front = (front+1)%MAX - 查看队头:直接返回front位置的元素(不改变front) 但是,循环队列的队满条件通常有两种处理方式: 1. 使用一个额外的变量记录元素个数。 2. 牺牲一个存储单元(即我们上面采用的方式)。 我们这里采用牺牲一个存储单元的方式,即队列最多存储MAX-1个元素。 下面用C语言代码实现实现: */ #define MAX 100 typedef struct { int data[MAX]; int top; } Stack; void initStack(Stack *s) { s->top = -1; } int isStackEmpty(Stack *s) { return s->top == -1; } int isStackFull(Stack *s) { return s->top == MAX - 1; } int push(Stack *s, int value) { if (isStackFull(s)) { return 0; // 满,返回0表示失败 } s->top++; s->data[s->top] = value; return 1; // 成功 } int pop(Stack *s, int *value) { if (isStackEmpty(s)) { return 0; // 空,返回0表示失败 } *value = s->data[s->top]; s->top--; return 1; // 成功 } int peek(Stack *s, int *value) { if (isStackEmpty(s)) { return 0; } *value = s->data[s->top]; return 1; } /* 队列实现(循环队列,牺牲一个单元): */ typedef struct { int data[MAX]; int front; int rear; } Queue; void initQueue(Queue *q) { q->front = 0; q->rear = 0; } int isQueueEmpty(Queue *q) { return q->front == q->rear; } int isQueueFull(Queue *q) { return (q->rear + 1) % MAX == q->front; } int enqueue(Queue *q, int value) { if (isQueueFull(q)) { return 0; // 队满,失败 } q->data[q->rear] = value; q->rear = (q->rear + 1) % MAX; return 1; // 成功 } int dequeue(Queue *q, int *value) { if (isQueueEmpty(q)) { return 0; // 队空,失败 } *value = q->data[q->front]; q->front = (q->front + 1) % MAX; return 1; // 成功 } int front(Queue *q, int *value) { if (isQueueEmpty(q)) { return 0; } *value = q->data[q->front]; return 1; } /* 注意:这里队列实现是循环队列,因此入队出队操作中rearfront的移动都是取模运算。 以上代码提供了队列的基本操作。在实际使用中,我们还需要考虑错误处理(比如空时出等),上面的函数通过返回值来表示操作是否成功。 相关问题: 1. 在循环队列中,为什么牺牲一个存储单元可以区分队空队满?还有其他方法吗? 2. 在函数调用中的应用有哪些? 3. 队列在操作系统中的哪些地方有应用? 4. 如何用两个实现一个队列? 5. 如何用两个队列实现一个? </think> ### 使用数组实现队列的C语言方法 #### 一、实现(后进先出 LIFO) 的核心操作:`push()`(入)、`pop()`(出)、`peek()`(查看顶) ```c #include <stdio.h> #define MAX_SIZE 100 typedef struct { int data[MAX_SIZE]; int top; // 顶指针 } Stack; // 初始化 void initStack(Stack* s) { s->top = -1; } // 入操作 void push(Stack* s, int value) { if (s->top >= MAX_SIZE - 1) { printf("已满\n"); return; } s->data[++s->top] = value; } // 出操作 int pop(Stack* s) { if (s->top == -1) { printf("已空\n"); return -1; } return s->data[s->top--]; } // 查看顶元素 int peek(Stack* s) { if (s->top == -1) { printf("为空\n"); return -1; } return s->data[s->top]; } ``` #### 二、队列实现(先进先出 FIFO) 队列的核心操作:`enqueue()`(入队)、`dequeue()`(出队)、`front()`(查看队首) ```c typedef struct { int data[MAX_SIZE]; int front; // 队头指针 int rear; // 队尾指针 } Queue; // 初始化队列 void initQueue(Queue* q) { q->front = 0; q->rear = -1; } // 入队操作 void enqueue(Queue* q, int value) { if (q->rear == MAX_SIZE - 1) { printf("队列已满\n"); return; } q->data[++q->rear] = value; } // 出队操作 int dequeue(Queue* q) { if (q->front > q->rear) { printf("队列已空\n"); return -1; } return q->data[q->front++]; } // 查看队首元素 int front(Queue* q) { if (q->front > q->rear) { printf("队列为空\n"); return -1; } return q->data[q->front]; } ``` #### 三、关键区别与特点 1. **** - 单指针操作(`top`) - 时间复杂度:所有操作 $O(1)$ - 应用场景:函数调用、表达式求值、括号匹配[^1] 2. **队列** - 双指针操作(`front``rear`) - 循环队列可优化空间利用率(修改指针移动逻辑) - 应用场景:任务调度、缓冲区管理、BFS算法[^2] #### 四、使用示例 ```c int main() { // 测试 Stack s; initStack(&s); push(&s, 10); push(&s, 20); printf("顶: %d\n", peek(&s)); // 输出 20 printf("出: %d\n", pop(&s)); // 输出 20 // 队列测试 Queue q; initQueue(&q); enqueue(&q, 30); enqueue(&q, 40); printf("队首: %d\n", front(&q)); // 输出 30 printf("出队: %d\n", dequeue(&q)); // 输出 30 } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值