【数据结构与算法】task2 栈&队列&递归

栈(stack)

,堆栈,是一种容器,可存入数据元素、访问元素、删除元素。

它的特点在于只能允许在容器的一端(称为栈顶端指标,top)进行加入数据(push)和输出数据(pop)的运算。没有了位置概念,保证任何时候可以访问、删除的元素都是此前最后存入的那个元素,按照后进先出(LIFO, Last In First Out)的原理运作。

应用场景:函数调用。如:函数A调用B,B调用C,最后调用的C,但执行时是C先执行,返回,然后B执行,返回,A再执行,返回;在调用当前函数时会将局部变量和参数入栈,函数返回时会销毁当前函数的局部变量和参数,出栈。

队列先进先出)是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。

例如同样是在线性表中 "按顺序" 插入1,2,3,4:

对于栈,只允许在尾部删除,所以先出栈的将会是4,即后进先出;

对于队列,只允许在头部删除,所以先出队的是1,即先进先出。

用数组实现一个顺序栈

参考:https://blog.csdn.net/weixin_40283816/article/details/87890661

https://blog.csdn.net/mydistance/article/details/86024862

class SequenceStack:
    def __init__(self):
        self.MaxStackSize = 10
        self.s = [None for x in range(0,self.MaxStackSize)]
        self.top = -1
        
    '''判断栈是否为空'''
    def IsEmptyStack(self):
        if self.top == -1:
            iTop = True
        else:
            iTop = False
        return iTop
    '''进栈'''
    def PushStaxk(self,x):
        if self.top < self.MaxStackSize-1:
            self.top = self.top+1
            self.s[self.top] = x
        else:
            print("栈满")
            return
    '''出栈'''
    def PopStack(self):
        if self.IsEmptyStack == True:
            print("栈为空")
            return
        else:
            iTop = self.top
            self.top = self.top-1
            return self.s[iTop]
    '''获取栈顶元素'''
    def GetTopStack(self):
        if self.IsEmptyStack == True:
            return "栈为空"
        else:
            return self.s[self.top]
    '''遍历栈内元素'''
    def StackTraverse(self):
        if self.IsEmptyStack == True:
            return "栈为空"
        else:
            for i in range(0,self.top + 1):
                print(self.s[i],end = ' ')
    '''创建一个顺序栈'''
    def CreateStackByInput(self):
        data = input("请输入元素(确定按回车键,结束按“#”):")
        while data != "#":
            self.PushStaxk(data)
            data = input("请输入元素(确定按回车键,结束按“#”):")
    '''获取顺序栈的长度'''
    def GetStackLength(self):
        num = 0
        for i in range(0,self.top + 1):
            num = num+1
        return num
ss = SequenceStack()
ss.CreateStackByInput()
print("栈内元素为:",end = " ")
ss.StackTraverse()
print("\n栈顶元素为:",ss.GetTopStack())
print("顺序栈的长度为:",ss.GetStackLength())

用链表实现一个链式栈

参考:https://www.cnblogs.com/cxc1357/p/10295369.html

https://blog.csdn.net/chenyuxiang0425/article/details/83422854

class Stack:
    def __init__(self):
        self._first = None
    def push(self,item):
        self._first = _Node(item,self._first)
    def pop(self):
        self._first = self._first.next        
    def isEmpty(self):
        return self._first is None
class _Node:
    def __init__(self,item,next):
        self.item = item
        self.next = next
        
def main():
    stack = Stack()
    stack.push("a")
    stack.push("b")
    stack.push("c")
    print(stack._first.item)
    print(stack._first.next.item)
    print(stack._first.next.next.item)
        
if __name__ == "__main__":
    main() 

运行结果:
>> c
>> b
>> a 

编程模拟实现一个浏览器的前进、后退功能

参考:https://github.com/wangzheng0822/algo/tree/master/python/08_stack

思路:我们使用两个栈,X 和 Y,我们把首次浏览的页面依次压入栈 X,当点击后退按钮时,再依次从栈 X 中出栈,并将出栈的数据依次放入栈 Y。当我们点击前进按钮时,我们依次从栈 Y 中取出数据,放入栈 X 中。当栈 X 中没有数据时,那就说明没有页面可以继续后退浏览了。当栈 Y 中没有数据,那就说明没有页面可以点击前进按钮浏览了。

import sys
# 引用当前文件夹下的single_linked_list
sys.path.append('linked_stack.py')
from linked_stack import LinkedStack
#from .linked_stack import LinkedStack

class NewLinkedStack(LinkedStack):

    def is_empty(self):
        return not self._top


class Browser():

    def __init__(self):
        self.forward_stack = NewLinkedStack()
        self.back_stack = NewLinkedStack()

    def can_forward(self):
        if self.back_stack.is_empty():
            return False

        return True

    def can_back(self):
        if self.forward_stack.is_empty():
            return False

        return True

    def open(self, url):
        print("Open new url %s" % url, end="\n")
        self.forward_stack.push(url)

    def back(self):
        if self.forward_stack.is_empty():
            return

        top = self.forward_stack.pop()
        self.back_stack.push(top)
        print("back to %s" % top, end="\n")

    def forward(self):
        if self.back_stack.is_empty():
            return

        top = self.back_stack.pop()
        self.forward_stack.push(top)
        print("forward to %s" % top, end="\n")


if __name__ == '__main__':

    browser = Browser()
    browser.open('a')
    browser.open('b')
    browser.open('c')
    if browser.can_back():
        browser.back()

    if browser.can_forward():
        browser.forward()

    browser.back()
    browser.back()
    browser.back()

linked_stack.py

"""
    Stack based upon linked list
    基于链表实现的栈
"""

from typing import Optional

class Node:
    
    def __init__(self, data: int, next=None):
        self._data = data
        self._next = next
    

class LinkedStack:
    """A stack based upon singly-linked list.
    """
    def __init__(self):
        self._top: Node = None
    
    def push(self, value: int):
        new_top = Node(value)
        new_top._next = self._top
        self._top = new_top
    
    def pop(self) -> Optional[int]:
        if self._top:
            value = self._top._data
            self._top = self._top._next
            return value
    
    def __repr__(self) -> str:
        current = self._top
        nums = []
        while current:
            nums.append(current._data)
            current = current._next
        return " ".join(f"{num}]" for num in nums)

if __name__ == "__main__":
    stack = LinkedStack()
    for i in range(9):
        stack.push(i)
    print(stack)
    for _ in range(3):
        stack.pop()
    print(stack)

队列

用数组实现一个顺序队列

参考:http://www.cnblogs.com/dairuiquan/p/10380504.html

https://github.com/wangzheng0822/algo/blob/master/python/09_queue/array_queue.py

# 数组有一个固定的长度。头指针和尾指针,都指向数组第一个值。
# 当进行push操作的时候,头指针后移。当进行pop操作的时候,尾指针向后移
# 当到达最后一个值的时候,重新指向第一个值。取模 %queue_size()

# 首先实现一个数组
class Array(object):
    def __init__(self,size = 32):
        self._size = size
        self._items = [None] * size  # 容器_items, 是一个每个值为None的列表

    def __getitem__(self, index):      # 实现下标访问
        return self._items[index]

    def __setitem__(self, index, value):
        self._items[index] = value

    def __len__(self):
        return self._size

    def clear(self, value=None):
        for i in range(len(self._items)):
            self._items[i] = value

    def __iter__(self):
        for item in self._items:
            yield item


class ArrayQueue(object):
    def __init__(self, maxsize):
        self.maxsize = maxsize
        self.array = Array(maxsize)
        self.head = 0
        self.tail = 0

    def push(self, value):
        if len(self) >= self.maxsize:
            raise Exception('queue full')
        self.array[self.head % self.maxsize] = value
        self.head += 1

    def pop(self):
        value = self.array[self.tail % self.maxsize]
        self.tail += 1
        return value

    def __len__(self):
        return self.head - self.tail

用链表实现一个链式队列

参考:https://blog.csdn.net/weixin_40283816/article/details/87952682

https://github.com/wangzheng0822/algo/blob/master/python/09_queue/linked_queue.py

链式队列在创建一个队列时,队头指针front和队尾指针rear指向结点的data域和next域均为空。

class QueueNode():
    def __init__(self):
        self.data = None
        self.next = None
class LinkQueue():
    def __init__(self):
        tQueueNode = QueueNode()
        self.front = tQueueNode
        self.rear = tQueueNode
    '''判断是否为空'''
    def IsEmptyQueue(self):
        if self.front == self.rear:
            iQueue = True
        else:
            iQueue = False
        return iQueue
    '''进队列'''
    def EnQueue(self,da):
        tQueueNode = QueueNode()
        tQueueNode.data = da
        self.rear.next = tQueueNode
        self.rear = tQueueNode
        print("当前进队的元素为:",da)
    '''出队列'''
    def DeQueue(self):
        if self.IsEmptyQueue():
            print("队列为空")
            return
        else:
            tQueueNode = self.front.next
            self.front.next = tQueueNode.next
            if self.rear == tQueueNode:
                self.rear = self.front
            return tQueueNode.data
    def  GetHead(self):
        if self.IsEmptyQueue():
            print("队列为空")
            return
        else:
            return self.front.next.data
    def CreateQueueByInput(self):
        data = input("请输入元素(回车键确定,#结束)")
        while data != "#":
            self.EnQueue(data)
            data = input("请输入元素(回车键确定,#结束)")
    '''遍历顺序队列内的所有元素'''
    def QueueTraverse(self):
        if self.IsEmptyQueue():
            print("队列为空")
            return
        else:
            while self.front != self.rear:
                result = self.DeQueue()
                print(result,end = ' ')
lq = LinkQueue()
lq.CreateQueueByInput()
print("队列里元素为:")
lq.QueueTraverse()

实现一个循环队列

参考:https://blog.csdn.net/u012626619/article/details/80658397

https://github.com/wangzheng0822/algo/blob/master/python/09_queue/circular_queue.py

http://www.cnblogs.com/xiaxuexiaoab/p/8593146.html

class SqQueue(object):
    def __init__(self, maxsize):
        self.queue = [None] * maxsize
        self.maxsize = maxsize
        self.front = 0
        self.rear = 0

    # 返回当前队列的长度
    def QueueLength(self):
        return (self.rear - self.front + self.maxsize) % self.maxsize

    # 如果队列未满,则在队尾插入元素,时间复杂度O(1)
    def EnQueue(self, data):
        if (self.rear + 1) % self.maxsize == self.front:
            print("The queue is full!")
        else:
            self.queue[self.rear] = data
           # self.queue.insert(self.rear,data)
            self.rear = (self.rear + 1) % self.maxsize

    # 如果队列不为空,则删除队头的元素,时间复杂度O(1)
    def DeQueue(self):
        if self.rear == self.front:
            print("The queue is empty!")
        else:
            data = self.queue[self.front]
            self.queue[self.front] = None
            self.front = (self.front + 1) % self.maxsize
            return data

    # 输出队列中的元素
    def ShowQueue(self):
        for i in range(self.maxsize):
            print(self.queue[i],end=',')
        print(' ')
# 测试程序
if __name__ == "__main__":
    # 建立大小为15的循环队列
    q = SqQueue(15)
    # 0~9入队列
    for i in range(10):
        q.EnQueue(i)
    q.ShowQueue()
    # 删除队头的5个元素:0~4
    for i in range(5):
        q.DeQueue()
    q.ShowQueue()
    # 从队尾增加8个元素:0~7
    for i in range(8):
        q.EnQueue(i)
    q.ShowQueue()

递归

编程实现斐波那契数列求值 f(n)=f(n-1)+f(n-2)

参考:https://blog.csdn.net/weixin_42793426/article/details/82996658

# 递归方式实现 生成前20项
lis =[]
for i in range(20):
    if i ==0 or i ==1:#第1,2项 都为1
        lis.append(1)
    else:
        lis.append(lis[i-2]+lis[i-1])#从第3项开始每项值为前两项值之和
print(lis)
def func(n):
    # 给递归一个出口  第一位和第二位都是1
    if n == 1 or n == 2:
        return 1
    else:
        # 从第三位开始  返回上一个数加上上一个数
        return func(n-1) + func(n-2)
res = func(20)
print(res)

编程实现求阶乘 n!

参考:https://www.cnblogs.com/iderek/p/5969992.html

def f(x):
    if x == 0:
        return 0
    elif x == 1:
        return 1
    else:
        return (x * f(x-1))
print(f(5))

编程实现一组数据集合的全排列

参考:https://blog.csdn.net/zhoufen12345/article/details/53560099

COUNT=0
def perm(n,begin,end):
    global COUNT
    if begin>=end:
        print n
        COUNT +=1
    else:
        i=begin
        for num in range(begin,end):
            n[num],n[i]=n[i],n[num]
            perm(n,begin+1,end)
            n[num],n[i]=n[i],n[num]
 
n=[1,2,3,4]
perm(n,0,len(n))
print COUNT

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值