数据结构-栈

     由于节后有面试,现在又把以前的学习的数据结构和算法知识拿出来重新温习一下,之所以要温习,因为上周去面试的时候发现很多问题自己有思路,但是用代码实现却觉得比较困难,大多数觉得很轻松很简单的数据结构和算法题,对一些细节却模糊了。温故而知新,以前大多数是c或者java实现的,因为最近用python比较多,那就用python来实现以下。

     栈,是计算机中比较重要的算法,其特点具有后进先出。事实上,向python和javascript这样的解释性语言或者说具有辅助编译性特点的语言。其类型中数组的操作就具有栈的特点。比如Array.push,Array.pop等方法。因为是数组,所以栈的结构是顺序性的,也就是默认申请一个数组,动态的对数组进行管理。对数组的动态管理是有成本的,频繁的删除、插入操作会导致栈的性能较差,因此大多数栈会使用链表来实现,因为对os来讲向堆中申请内存是比较充裕的。下面就来看看链表栈的实现:

from abc import ABCMeta, abstractmethod,abstractproperty
class IStack:
    __metaclass__=ABCMeta
    @abstractmethod
    def Push(self):pass
    @abstractmethod
    def Pop(self):pass
    @abstractmethod
    def Top(self):pass
    @abstractproperty
    def IsEmpty(self):pass
    @abstractproperty
    def Length(self):pass
    @abstractmethod
    def Display(self):pass

首先定义了一个IStack的接口(虽然python不想csharp那样具有定义接口的定制语法,但是python给使用者提供了一种类似接口的方式特性,比如twisted就是zope的实现)。其中,abc模块包含了一个叫做ABCMeta的metaclass。这个metaclass由内置的isinstance()和issubclass()特别处理,并包含一批会被Python开发人员广泛用到的基础抽象基类。将来的Python版本可能会加入更多的抽象基类。定义一个接口的好处就是在实现IStack这个接口的类会检查是否完整基础了接口,否则会抛出异常。因为python是弱类型的。

同时,还需要定义每个节点的数据接口,以方便我们的操作

class Node(object):def __init__(self,elem=None,node=None):
        self.__element=elem
        self.__next=node
    @property
    def Element(self):return self.__element
    @Element.setter
    def Element(self,val):self.__element=val
    @property
    def Next(self):return self.__next
    @Next.setter
    def Next(self,val):self.__next=val

里面有关于Element和Next的属性,以上的python的属性是通过decorate实现的。当然有很多其他的方式,比如动态的__getter__方式,这样写无非可以是代码更清晰。

链表栈的实现

from IStack import IStack
from Node import Node

class LinkStack(IStack):    
    def __init__(self):
        self.__top=None
        self.__length=0
    def Push(self,element):
        node=Node(elem=element,node=self.__top)
        self.__top=node
        self.__length+=1
        return True
    def Pop(self):
        if(self.__length==0):raise Exception('栈为空')
        elem=self.__top.Element
        self.__top=self.__top.Next
        self.__length-=1
        return elem
    def Top(self):
        if(self.__length==0):raise Exception('栈为空')
        return self.__top.Element
    def IsEmpty(self):
        if(self.__length==0):return True
        else:return False
    def Length(self):
        return self.__length
    def Display(self):
        data=[]
        cur=self.__top
        while(cur):
            data.append(cur.Element)
            cur=cur.Next
        return data

这里面__top和__length记录栈的边界和目前大小,以方便其他操作。

原文地址:https://www.cnblogs.com/keily/p/3354480.html