用堆栈做队列

2 篇文章 0 订阅
2 篇文章 0 订阅

程序中的临时变量都是存放在进程的堆栈中的,那么要实现队列,只需要在一次函数调用中不释放函数中的局部变量,然后让一个指针始终指向队列头,另一个指针始终指向队列的第二个成员就可以了。这时,就需要被调用的函数不能退出,那么它的所有局部变量就不会被释放。


为了做一个例子,我们让一个函数递归调用它自身,知道满足一定条件以后,才能把堆栈中的函数取出来继续执行。当然,在现实中,更多的情况是某些进程因为资源竞争而等不到资源,只好被迫睡眠,这就可以使用堆栈的方式来创建一个等待队列。


实例程序的过程:有一全局变量的指针,始终指向队列的头元素,把它叫做head好了;在函数中,有一局部变量lnode和一个局部变量的指针tmp。函数的功能就是给lnode赋值,并且判断条件是否成立:如果不成立,则递归调用该函数;如果成立,就把函数出栈,打印队列头的值,并把队列头向后移动一个位置。


#include <stdio.h>

struct node {
	int id;
};
static struct node *head;  //全局头指针

/* 判断条件:
 * 如果某一个flags[i]为1,这递归调用,知道所有的flags[i]都为0
 */ 
static int flags[5] = { 1, 1, 1, 1, 1 };
static int done = 0;  //函数从栈中弹出时,需要判断是否所有的flags[i]都已经为0

void recursion()
{
	struct node lnode;  //局部变量
	struct node *tmp;  //局部变量指针,指向队列的第二个元素
	int i;

	for (i=0; i<5; i++) {
		if (flags[i]) {  //如果flags[i]不为0
			flags[i] = 0;
			lnode.id = i + 1;  //给局部变量赋值
			tmp = head;  //让tmp指向队列的第二个元素
			head = &lnode;  //让head指向队列的头
			recursion();
		}
                /* 以下代码只有从栈中弹出的函数会执行 */
                if (done) {
			head = tmp;
			break;
		}
	}
        /* 以下代码会在最后一次调用recursion()(也就是在所有已入栈的函数出栈前)时第一次被执行
         * 设置done标志,让从栈中弹出的函数知道flags[i]已经都为0了,需要把head指针向后移一位
         */
        done = 1;
	if (head)  //如果head不为空,为空说明栈中的数据已经取完了
		printf("%d\n", head->id);
}

int main()
{
	recursion();
	return 0;
}

最后执行结果会打印出 5, 4, 3, 2, 1。如果代码我解释得不太清除,可以结合gdb调一下,很容易看清楚这个过程的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值