栈与队列

栈与队列

后进先出结构,向量(Vector)的派生类。

栈 ADT 支持的操作接口

操作接口功能
size()返回栈规模
empty()判断栈是否为空
push(e)将 e 插至栈顶
pop()删除栈顶对象
top()引用栈顶对象

Stack 模板类

#include "../Vector/Vector.h" //以向量为基类,派生出栈模板类
template <typename T> class Stack: public Vector<T> { //将向量的首/末端作为栈底/顶
public: //size()、empty() 以及其他开放接口,均可直接沿用
	void push ( T const& e ) { insert ( size(), e ); } // 入栈:等效于将新元素作为向量的末元素插入
	T pop() { return remove ( size() - 1 ); } //出栈:等效于删除向量的末元素
	T& top() { return ( *this ) [size() - 1]; } //取顶:直接返回向量的末元素
};

递归几乎都是通过栈结构来支持过程调用,每一次调用都会调用栈,每一次调用栈都要对参数和变量进行相应的维护,这往往导致程序的 空间效率 不高甚至极低。
因此在追求高效率的场合,应尽可能的避免递归,尤其是过度的递归。

递归

void convert ( Stack<char>& S, __int64 n, int base ) { //整数n的1<base<=16进制打印(递归版)
   static char digit[] = "0123456789ABCDEF"; //数位符号,如有必要可相应扩充
   if ( 0 < n ) { //在尚有余数之前,反复地
      S.push ( digit[n % base] ); //逆向记录当前最低位,再
      convert ( S, n / base, base ); //通过递归得到所有更高位
   }
} //新进制下由高到低的各数位,自顶而下保存于栈S中void convert ( Stack<char>& S, __int64 n, int base ) { 
  //整数n的1<base<=16进制打印(递归版)
   static char digit[] = "0123456789ABCDEF"; //数位符号,如有必要可相应扩充
   if ( 0 < n ) { //在尚有余数之前,反复地
      S.push ( digit[n % base] ); //逆向记录当前最低位,再
      convert ( S, n / base, base ); //通过递归得到所有更高位
   }
} //新进制下由高到低的各数位,自顶而下保存于栈S中

迭代

void convert ( Stack<char>& S, __int64 n, int base ) { //整数n的1<base<=16进制打印(迭代版)
   char digit[] = "0123456789ABCDEF"; //数位符号,如有必要可相应扩充
   while ( n > 0 ) { //由低到高,逐一计算出新进制下的各数位
      S.push ( digit[ n % base ] ); //余数(当前位)入栈
      n /= base; //n更新为其对base的除商
   }
} //新进制下由高到低的各数位,自顶而下保存于栈S中void convert ( Stack<char>& S, __int64 n, int base ) { 
  //整数n的1<base<=16进制打印(迭代版)
   char digit[] = "0123456789ABCDEF"; //数位符号,如有必要可相应扩充
   while ( n > 0 ) { //由低到高,逐一计算出新进制下的各数位
      S.push ( digit[ n % base ] ); //余数(当前位)入栈
      n /= base; //n更新为其对base的除商
   }
} //新进制下由高到低的各数位,自顶而下保存于栈S中

显然迭代实现空间效率高很多。

队列

先进先出结构,列表(List)的派生类。

队列 ADT 支持的操作接口

操作功能
size()返回队列元素总数
empty()判断队列是否为空
enqueue(e)将 e 插入队尾
dequeue()删除队首对象
front()引用队首对象

Queue 模板类

#include "../List/List.h" // 以 List 为基类
template <template T> class Queue: public List<T> { // 队列模板类(继承List原有接口)
public: // size()、empty()以及其他开发接口均可直接沿用
	void enqueue ( T const& e ) { insertAsLast ( e ); } // 入队:队尾插入
	T dequeue() { return remove ( first() ); } // 出队:首部删除
	T& front() { return first()->data; } // 队首
};

队列的引用 — 循环分配器

RoundRobin { //循环分配器
	Queue Q(clients); //参与资源分配的所有客户组成队列 Q
	while (!ServiceClosed()) { // 在服务关闭之前,反复地
	e = Q.dequeue(); // 队首的客户出队,并
	service(e); // 接受服务,然后
	Q.enqueue(e); // 重新入队
	}
}

上述轮值算法的调度过程:取出当前位于对头的客户,将资源交予该客户使用;在经过固定时间后,收回资源,并令该客户重新入队。
得益于队列 “ 先进先出 ” 的特性,如此既可在所有客户之间达成一种均衡的公平,也可使得资源得以充分利用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值