Python数据结构第一天—栈、队列、单向链表

数据结构与算法

1、什么是数据结构

我认为的数据结构就是计算机中存储、组织数据的方式

在《数据结构与算法分析》一书中,把数据结构称为抽象数据类型(ADT)

而什么又是ADT呢?

ADT,抽象数据类型,我们在组合已有的数据结构来实现一种新的数据类型,ADT定义了类型的数据和操作

我们以抽象一个背包(Bag) 数据类型来说明,背包是一种容器类型,我们可以给它添加东西,也可以移除东西,并且我们想知道背包里有多少东西。于是我们可以定义一个新的数据类型叫做 Bag,在类中实现背包的所有功能.

class Bag:
    """ 背包类型 """
    pass

2、栈

栈(stack)是一种运算受限的线性表,他符合先进后出的一个原则,就是最先进去的数据反而是最后出来的。

类似于平时收作业,先收到的作业放在最下面,后收到的作业放在最上面。发作业的时候后收到的作业先发出去,先收到的作业后发出去。

栈的限制就是只允许在表的一端进行插入和删除,这一端被称为栈顶,而另外一端被称为栈底。

向栈内添加一个元素被称为进栈(入栈、压栈)它是把新的元素放在栈顶元素的上面。让该元素称为新的栈顶元素。

从栈内取出数据又叫出栈或退栈,它是把栈顶元素删除掉,使其下面的元素成为新的栈顶元素。

栈常见的操作

  • push(element): 添加一个新元素到栈顶位置.
  • pop():移除栈顶的元素,同时返回被移除的元素。
  • peek():返回栈顶的元素,不对栈做任何修改(这个方法不会移除栈顶的元素,仅仅返回它)。
  • isEmpty():如果栈里没有任何元素就返回true,否则返回false
  • clear():移除栈里的所有元素。
  • size():返回栈里的元素个数。这个方法和数组的length属性很类似。

栈的实现:

class Stack:
    def __init__(self):
        #初始化一个私有变量用来存储之后的数据对象
        self.__items = []
        #添加一个新元素到栈顶位置
    def push(self,element):
        self.__items.append(element)
        #移除栈顶的元素,同时返回被移除的元素。
    def pop(self):
        return self.__items.pop()
        #返回栈顶的元素,不对栈做任何修改(这个方法不会移除栈顶的元素,仅仅返回它)
    def peek(self):
        return self.__items[-1]
        #如果栈里没有任何元素就返回`true`,否则返回`false`。
    def is_empty(self):
        return len(self.__items)==0
        #移除栈里的所有元素
    def clear(self):
        self.__items.clear()
        #返回栈里的元素个数。这个方法和数组的`length`属性很类似。
    def size(self):
        return len(self.__items)

3、队列

队列(queue),它也是一种运算受限的线性表,它遵循一个先进先出原则。

它的受限之处在于它只允许在表的前端进行删除操作,而在表的后端进行添加操作。

就类似于生活中的排队打饭,先排队的先打饭然后离开,后来的人只能排在队伍的末尾,要等前面的人离开后,后面的人才能打饭。

队列常见的操作

  • enqueue(element):向队列尾部添加一个(或多个)新的项。
  • dequeue():移除队列的第一(即排在队列最前面的)项,并返回被移除的元素。
  • front():返回当前队列中第一个元素,也将是最先被移除的元素。队列不做任何变动(不移除元素,只返回元素信息——与Stack类的peek方法非常类似)。
  • isEmpty():如果队列中不包含任何元素,返回true,否则返回false
  • size():返回队列包含的元素个数,与数组的length属性类似.

普通队列的实现

class Queue:
    def __init__(self):
        self.__items = []
    def enqueue(self,element):
        self.__items.append(element)
    def dequeue(self):
        if len(self.__items)==0:
            return None
        self.__items.pop(0)
    def front(self):
        if len(self.__items)==0:
            return None
        return self.__items[0]
    def is_empty(self):
        return len(self.__items)==0
    def size(self):
        return len(self.__items)

优先级队列

优先级队列的特点:

  • 我们知道, 普通的队列插入一个元素, 数据会被放在后端. 并且需要前面所有的元素都处理完成后才会处理前面的数据.
  • 但是优先级队列, 在插入一个元素的时候会考虑该数据的优先级.(和其他数据优先级进行比较)
  • 比较完成后, 可以得出这个元素正确的队列中的位置. 其他处理方式, 和队列的处理方式一样.
  • 也就是说, 如果我们要实现优先级队列, 最主要是要修改添加方法. (当然, 还需要以某种方式来保存元素的优先级)

优先级队列的实现:

实现优先级队列相对队列主要有两方面需要考虑:

1、封装元素和优先级放在一起(可以封装一个新的类)

2、添加元素时, 将当前的优先级和队列中已经存在的元素优先级进行比较, 以获得自己正确的位置.

class Node:
    def __init__(self,element,rank):
        self.element = element
        self.rank = rank
class Queue:
    def __init__(self):
        self.__items = []
    def enqueue(self,element,rank):
        node = Node(element,rank)
        flag = True
        for i in range(len(self.__items)):
            if node.rank < self.__items[i].rank:
                self.__items.insert(i,node)
                flag = False
                break
        if flag:
            self.__items.append(node)
    def dequeue(self):
        if self.is_empty():
            return None
        return self.__items.pop(0)
    def front(self):
        if self.is_empty():
            return None
        return self.__items[0]

    def is_empty(self):
        return len(self.__items) == 0
    def size(self):
        return len(self.__items)
q2=Queue()
q2.enqueue("jack2",1)
q2.enqueue("jack3",1)
q2.enqueue("jack",2)
q2.enqueue("jack4",2)
q2.enqueue("jack3",3)
q2.enqueue("karen",1)

print("取出优先队列中的第一个元素:",q2.dequeue().element)
print("取出优先队列中的第一个元素:",q2.dequeue().element)
print("取出优先队列中的第一个元素:",q2.dequeue().element)

4、链表

链表是链式的存储多个元素

但不同于列表,链表中的元素在内存中不必是连续的空间

链表的每一个元素由一个存储元素本身的节点和一个指向下一个元素的引用(有些语言也称指针或者链接)组成。

链表访问任何一个位置的元素时,都需要从头开始访问(无法跳过第一个元素访问任何一个元素)

链表常见的操作

  • append(element):向列表尾部添加一个新的项

  • insert(position, element):向列表的特定位置插入一个新的项。

  • remove(element):从列表中移除一项。

  • indexOf(element):返回元素在链表中的索引。如果列表中没有该元素则返回-1

  • removeAt(position):从列表的特定位置移除一项。

  • isEmpty():如果链表中不包含任何元素,返回true,如果链表长度大于0则返回false

  • size():返回链表包含的元素个数。与数组的length属性类似。

1、单向链表的实现

class Node:
    def __init__(self,element):
        self.element = element
        self.next = None
class Linklist:
    def __init__(self):
        self.length = 0
        self.head = None
    def append(self,element):
        node = Node(element)
        if self.head == None:
            self.head = node
        else:
            temp = self.head
            while temp.next != None:
                temp = temp.next
            temp.next = node
        self.length += 1

    def insert(self, position, element):
        # 检测越界问题: 越界插入失败
        if (position < 0 or position > self.length):
            return False
        # 定义变量, 保存信息
        newNode = Node(element)
        current = self.head
        previous = None
        index = 0
        if (position == 0):
            newNode.next = current
            self.head = newNode
        else:
            while (index < position):
                previous = current
                current = current.next
                index += 1
            newNode.next = current
            previous.next = newNode
        self.length += 1
        return True
    def index_of(self,element):
        if self.head == None:
            return None
        else:
            temp = self.head
            for i in range(self.length):
                if temp.element == element:
                    return i
                temp = temp.next
        return -1
    def removeAt(self,position):
        # 检测越界问题: 越界移除失败, 返回None
        if (position < 0 or position >= self.length):
            return None
        current = self.head
        previous = None
        index = 0
        if position == 0:
            self.head = current.next
        else:
            while index < position:
                previous = current
                current = current.next
                index += 1
            previous.next = current.next
            self.length -= 1
            return current.element
    def remove(self,elemnet):
        index = self.index_of(elemnet)
        return self.removeAt(index)

    def isEmpty(self):
        return self.length == 0
        # 获取链表的长度
    def size(self):
        return self.length


list1 = Linklist()
for i in range(6):
    list1.append(i)
print(list1.index_of("hello"))  # -1
print(list1.index_of(4))  # 4
print(list1.remove(4))  # 4
print(list1.size())

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值