现在的位置: 首页 > 综合 > 正文

Scheme数据结构——栈

2013年08月23日 ⁄ 综合 ⁄ 共 955字 ⁄ 字号 评论关闭

作为一种函数语言,Scheme认为一个函数,只要参数和变换过程一样,每一次的结果也必然是相同的。就好比函数y=x+1,当x=1是,y的值为2,不管哪一天都是这个结果。但对于真实世界来说,很多事物都是处于变化中的。因此Scheme中引入了set!、set-car!、set-cdr!等操作。

对于栈这样一种简单的数据结构,就必然要考虑变化。每次压入、弹出元素,都要改变栈。至于栈的表示,一个很自然的想法是用list,但这样会有一个问题:因为Scheme的参数传递方式为“值传递”,这样就无法通过一个函数来向一个空栈中添加元素。因此,我将栈包装成一个序对,前者指向一个list,表示栈,后者是一个整数,代表栈的长度。

(define (make-stack)
  (cons '() 0))

依据这样的定义,很容易写出判断栈是否为空的函数:

(define (empty-stack? stack)
  (= (cdr stack) 0))

如何取得栈顶元素呢?我规定最前面为顶,这样就有了top-stack:

(define (top-stack stack)
  (if (empty-stack? stack)
      (display "No element!")
      (caar stack)))

接下来是重头戏,压入和弹出。其实也不复杂。对于压入操作,只需要把新的元素粘到栈的前面即可,然后再修改一下栈顶指针(也就是(car stack)):

(define (push-stack! stack item)
  (let ((new-item (cons item (car stack))))
    (set-car! stack new-item)
    (set-cdr! stack (+ (cdr stack) 1))))

对于弹出操作,要确保栈里有元素。然后修改一下栈顶指针即可(可以让它返回弹出的元素):

(define (pop-stack! stack)
  (if (empty-stack? stack)
      (display "No element!")
      (let ((item (top-stack stack)))
        (set-car! stack (cdar stack))
        (set-cdr! stack (- (cdr stack) 1))
        item)))

抱歉!评论已关闭.