基于python的数据结构和算法(双向队列和线性结构的总结)

  • 双向队列:
    双端队列是一种有次序的数据集,数据项既可以从队首加入,也可以从队尾加入,数据项也可以从两端删除;某种意义上说,双端队列集成了栈和队列的能力。
    但双端队列并不具有内在的LIFO和FIFO特性,如果用双端队列来模拟栈和队列,需要由使用者自行维护操作的一致性。
    • 双向队列的操作:
      deque() 创建空双端队列
      addfront(item) 将item加入队首
      addrear(item) 将item加入队尾
      removefront() 从队首移除数据项,返回值为移除的数据项
      removerear() 从队尾移除数据项,返回值为移除的数据项
      isempty() 返回deque是否为空
      size() 返回deque中包含数据项的个数**
      举例如:
      基于python的数据结构和算法(双向队列和线性结构的总结)_第1张图片
      用代码实现为:
class Deque(object):
    def __init__(self):
        self.items = []

    def is_empty(self):
        return self.items == []

    def add_front(self, item):
        self.items.append(item)

    def add_rear(self, item):
        self.items.insert(0, item)

    def remove_front(self):
        return self.items.pop()

    def remove_rear(self):
        return self.items.pop(0)

    def size(self):
        return len(self.items)

  • 双向队列的应用–回文检测
    “回文”即为正读和反读相同的一个字符串(中文或英文皆可)。
    算法思想:
    用双端队列很容易解决回文词问题,先将需要判定的词从队尾加入deque,再从两端同时移除字符判定是否相同,直到deque中剩下0个或1个字符。
    (考虑回文的字数为奇数偶数不同的情况)
    自写为:
def palchecker(astring):
    deque = Deque()
    wordchecker = True
    for i in astring:
        deque.addrear(i)

    while deque.size() > 1 and wordchecker :
        temp1 = deque.removerear()
        temp2 = deque.removefront()
        if temp1 != temp2:
            wordchecker = False

    return wordchecker

print(palchecker('aialblaia'))
print(palchecker('word'))

缺点为所用变量名不够准确,代码自解释性笔记差。
标准代码为

def palchecker(aString):
    chardeque = Deque()

    for ch in aString:
        chardeque.addrear(ch)

    stillEqual = True
    while chardeque.size() > 1 and stillEqual:
        first = chardeque.removefront()
        last = chardeque.removerear()
        if first != last:
            stillEqual = False
    return stillEqual

print(palchecker("lsdkjfskf"))
print(palchecker("radar"))

  • 链表实现的无序表UnorderedList -

    • 什么是无序表?
      虽然列表数据结构要求保持数据项的前后相对位置,但这种前后位置的保持,并不要求数据项依次存放在连续的存储空间。
      如下图,数据项存放位置并没有规则,但如果在数据项之间建立链接指向,就可以保持其前后相对位置。第一个和最后一个数据项需要显示标记出来,一个是队首,一个是队尾,后面再无数据了。即为无序表。

基于python的数据结构和算法(双向队列和线性结构的总结)_第2张图片

 - 链表实现结点Node:

	链表实现的最基本元素是节点Node,每个节点至少要包含两个信息:数据项本身、以及指向下一个节点的引用信息。注意next为None的意义是没有下一个节点了。
链表实现无序表UnorderedList
可以采用链接节点的方式构建数据集来实现无序表。
  • 链表实现无序表UnorderedList

链表的第一个和最后一个节点最重要。如果想访问到链表中的所有节点,就必须从一个节点开始沿着链接遍历下去。
所以无序表必须要有对第一个节点的引用信息,设立一个属性head,保存对第一个节点的引用,空表的head为None。
随着数据项的加入,无序表的head始终指向链条的第一个节点,无序表mylist对象本身并不包含数据项(数据项在节点中)。其中包含的head只是对首个节点Node的引用,判断空表的isEmpty()很容易实现。
无序表实现add方法,按照实现的性能考虑,应该添加到最容易加入的位置上,也就是表头,整个链表的首位置。
如下图:
基于python的数据结构和算法(双向队列和线性结构的总结)_第3张图片

 - 链表实现 size
 从链表头head开始遍历到表尾同时用变量累加经过的节点个数。
 

 - 链表实现 search
 从链表头head开始遍历到表尾,同时判断当前节点的数据项是否为目标。

关键点:链表实现:remove(item)方法
首先找到item,这个过程和search一样,但删除节点时,需要特别的技巧。
current指向的是当前匹配数据项的节点,而删除需要把前一个节点的next指向current的下一个节点,所以我们在查找current的同时,还要维护前一个(previous)节点的引用。
基于python的数据结构和算法(双向队列和线性结构的总结)_第4张图片
找到item后,current指向item节点,previous指向前一个节点,开始执行删除,需要区分两种情况:current是首个节点;或者是位于链条中间的节点。
基于python的数据结构和算法(双向队列和线性结构的总结)_第5张图片
无整体标准代码,按局部修改为

class Node:
    def __init__(self,initdata):
        self.data = initdata
        self.next = None

    def getData(self):
        return self.data

    def getNext(self):
        return self.next

    def setData(self,newdata):
        self.data = newdata

    def setNext(self,newnext):
        self.next = newnext

class UnorderedList:
    def __init__(self):
        self.head = None

    def add(self,item):
        temp = Node(item)
        temp.setNext(self.head)
        self.head = temp

    def size(self):
        current = self.head
        count = 0
        while current != None:
            count = count + 1
            current = current.getNext()
        return count

    def search(self,item):
        current = self.head
        found = False
        while current != None and not found:
            if current.getData() == item:
                found = True
            else:
                current = current.getNext()
        return found

    def remove(self,item):
        current = self.head
        previous = None
        found = False
        while not found:
            if current.getData() == item:
                found = True
            else:
                previous = current
                current = current.getNext()
        if previous == None:
            self.head = current.getNext()
        else:
            previous.setNext(current.getNext())

  • 采用链表实现有序表OrderedList
    在实现有序表时,需要记住数据项的相对位置,取决于他们之间的“大小”比较,Node定义相同,OrderedList也设置一个head来保存链表表头的引用。
    对于isEmpty(),size(),remove()方法与节点次序无关,其实现与UnorderedList相同。
    search和add方法需要修改。
    • 有序表实现:search方法:
      在无序表的search中,如果需要查找的数据项不存在,则会搜遍整个链表,直到表尾。
      对于有序表来说,可以利用链表节点有序排列的特性,来为search节省不存在数据项的查找时间。一旦当前节点的数据项大于所要查找的数据项,则说明链表后面已经不可能再有要查找的数据项,可以直接返回False。
    • 有序表实现:add方法
      add方法必须保证加入的数据项添加在合适的位置,以维护整个链表的有序性。
      从头找到第一个比添加项大的数据项,将添加项插到该数据项前面。
      跟remove方法类似,引入一个previous,跟随当前节点current。

同上代码为:

class Node:
    def __init__(self,initdata):
        self.data = initdata
        self.next = None

    def getData(self):
        return self.data

    def getNext(self):
        return self.next

    def setData(self,newdata):
        self.data = newdata

    def setNext(self,newnext):
        self.next = newnext

class OrderedList:
    def __init__(self):
        self.head = None

    def search(self,item):
        current = self.head
        found = False
        stop = False
        while current != None and not found and not stop:
            if current.getData() == item:
                found = True
            else:
                if current.getData() > item:
                    stop = True
                else:
                    current = current.getNext()
        return found

    def add(self,item):
        current = self.head
        previous = None
        stop = False
        while current != None and not stop:
            if current.getData() > item:
                stop = True
            else:
                previous = current
                current = current.getNext()
        temp = Node(item)
        if previous == None:
            temp.setNext(self.head)
            self.head = temp
        else:
            temp.setNext(current)
            previous.setNext(temp)

你可能感兴趣的:(算法,队列)