数据结构(Python)

 1.什么是数据结构

        数据结构是一门研究非数值计算的程序设计的问题中的的操作对象,以及它们之间的关系,操作方式等相关问题的学科。

        官方定义:并没有。。。

        民间定义:

                “数据结构是数据对象,以及存在于该对象的实例和 组成实例的数据元素之间的各种联系。这些联系可以通过定义相关的函数来给出。” --- 《数据结构、算法与应用》

                “数据结构(data structure)是计算机中存储、组织数据的方式。通常情况下,精心选择的数据结构可以 带来最优效率的算法。” ---中文维基百科

                “数据结构是ADT(抽象数据类型 Abstract Data Type)的物理实现。” --- 《数据结构与算法分析》


2.常见的数据结构

        栈、队列、集合、树、链表、字典

常见的数据结构较多, 每一种都有其对应的应用场景, 不同的数据结构的不同操作性能是不同的:

        有的查询性能很快,有的插入速度很快,有的是插入头和尾速度很快有的做范围查找很快

        有的允许元素重复,有的不允许重复等等.在开发中如何选择,要根据具体的需求来选择

注意: 数据结构和语言无关, 基本常见的编程语言都有直接或者间接的使用上述常见的数据结构


3.数据结构的实用案例

3.1列表

        python内置列表数据结构

列表的方法:

序号方法
1list.append(obj)在列表末尾添加新的对象
2list.count(obj)统计某个元素在列表中出现的次数
3list.extend(seq)在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
4list.index(obj)从列表中找出某个值第一个匹配项的索引位置
5list.insert(index, obj)将对象插入列表
6list.pop(index=-1)移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
7list.remove(obj)移除列表中某个值的第一个匹配项
8list.reverse()反向列表中元素
9list.sort( key=None, reverse=False)对原列表进行排序
10list.clear()清空列表
11list.copy()复制列表

3.2字典

python内置字典数据结构

字典的方法:

序号函数及描述
1dict.clear()删除字典内所有元素
2dict.copy()返回一个字典的浅复制
3dict.fromkeys()创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值
4dict.get(key, default=None)返回指定键的值,如果键不在字典中返回 default 设置的默认值
5key in dict如果键在字典dict里返回true,否则返回false
6dict.items()以列表返回一个视图对象
7dict.keys()返回一个视图对象
8dict.setdefault(key, default=None)和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
9dict.update(dict2)把字典dict2的键/值对更新到dict里
10dict.values()返回一个视图对象
11pop(key,default)删除字典 key(键)所对应的值,返回被删除的值。
12popitem()返回并删除字典中的最后一对键和值。

3.3集合

        python内置字典数据结构

集合的方法

方法描述
add()为集合添加元素
clear()移除集合中的所有元素
copy()拷贝一个集合
difference()返回多个集合的差集
difference_update()移除集合中的元素,该元素在指定的集合也存在。
discard()删除集合中指定的元素
intersection()返回集合的交集
intersection_update()返回集合的交集。
isdisjoint()判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。
issubset()判断指定集合是否为该方法参数集合的子集。
issuperset()判断该方法的参数集合是否为指定集合的子集
pop()随机移除元素
remove()移除指定元素
symmetric_difference()返回两个集合中不重复的元素集合。
symmetric_difference_update()移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。
union()返回两个集合的并集
update()给集合添加元素
len()计算集合元素个数

3.4数组

        数组是最常用到的一种线性结构,其实 python 内置了一个 array 模块,但是大部人甚至从来没用过它。 Python 的 array 是内存连续、存储的都是同一数据类型的结构,而且只能存数值和字符

import array
# 创建一个整数数组
int_array = array.array('i', [1, 2, 3, 4, 5])

# 对数组进行操作的例子
int_array.append(6)  # 添加元素
int_array.pop(3)   # 删除索引为3的元素
value = int_array[2]  # 获取索引为2的元素
int_array[1] = 10   # 修改元素
length = len(int_array)  # 获取数组长度
print(length)
# 遍历数组
for num in int_array:
    print(num)
print(value)
# 注意:array模块不支持多维数组,只有一维数组功能

输出结果

5
1
10
3
5
6
3

可用的类型码:

'b' 代表 signed char
'B' 代表 unsigned char
'u' 代表 Py_UNICODE (Unicode character)
'h' 代表 signed short
'H' 代表 unsigned short
'i' 代表 signed int
'I' 代表 unsigned int
'l' 代表 signed long
'L' 代表 unsigned long
'q' 代表 signed long long
'Q' 代表 unsigned long long
'f' 代表 float
'd' 代表 double

数组方法:

append()——在数组末尾添加一个新项
buffer_info()——返回给出当前内存信息的信息
byteswap()——对数组的所有项进行Byteswap
count()——返回对象出现的次数
extend()——通过从可迭代对象中附加多个元素来扩展数组
fromfile()——从文件对象中读取项
fromlist()——从列表中追加项目
frombytes()——从字符串中附加项
index()——返回对象第一次出现的索引
insert()——在数组中指定的位置插入一个新项
pop()——删除并返回项目(默认最后一个)
remove()——删除对象的第一次出现
reverse()——反转数组中元素的顺序
tofile()——将所有项写入一个文件对象
tolist()——返回转换为普通列表的数组
tobytes()——返回转换为字符串的数组

3.5栈

        栈(stack),它是一种运算受限的线性表,后进先出(LIFO)

LIFO(last in first out)表示就是后进入的元素, 第一个弹出栈空间. 类似于自动餐托盘, 最后放上的托盘, 往往先把拿出去使用

class Stack:
    def __init__(self):
        self.items = []

    def push(self, data):
        self.items.append(data)

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

    def peek(self):
        return self.items[-1]

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

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

    def clear(self):
        self.items = []


def test001():
    s = Stack()
    s.push(1)
    s.push(2)
    s.push(3)
    res1 = s.pop()
    print(res1)  # 输出: 3
    print(s.peek())  # 输出: 2
    print(s.size())  # 输出: 2
    print(s.is_empty())  # 输出: False
    s.clear()
    print(s.is_empty())  # 输出: True

3.6队列

        队列(Queue),它是一种运算受限的线性表,先进先出(FIFO First In First Out)。

        队列是一种受限的线性结构,受限之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。

3.6.1普通队列

class Queue:
    def __init__(self):
        self.items = []  # 用列表来保存真正的数据 在Queue类中实现数据的 存取方法

    def enqueue(self, data):
        self.items.append(data)  # 添加数据到队列(放在列表的尾部

    def dequeue(self):
        return self.items.pop(0) # 移除并返回队列的第一个元素

    def front(self):
        return self.items[0] # 返回队列的第一个元素,但是不移除它

    def is_empty(self):
        return self.size() == 0 # 检查队列是否为空

    def size(self):
        return len(self.items) # 获取队列的大小

3.6.2 优先队列

class PriorityElement():
    def __init__(self, data, priority):
        self.data = data
        self.priority = priority
#用于封装数据和优先级,有两个属性:
#    data:存储数据元素
#    priorrity:存储元素的优先级

class PriorityQueue():
    def __init__(self):
        self.items = [] # 用于存储队列中的元素列表

    def enqueue(self, data, priority):
        el = PriorityElement(data, priority)  # 把添加进来的数据和级别封装为一个对象
        # el.priority self.items
        for i in range(len(self.items)):
            if self.items[i].priority > el.priority:
                self.items.insert(i, el)
                return
        self.items.append(el)

    # 创建一个 PriorityElement 对象 el,封装数据 data 和优先级 priority。
    # 遍历 self.items 列表,找到第一个优先级大于 el.priority 的位置 i,然后在该位置插入 el。
    # 如果遍历完整个列表都没有找到优先级大于 el.priority 的位置,就将 el 添加到列表的末尾。

    def dequeue(self):
        return self.items.pop(0) # 用于移除并且返回队列中的第一个元素

    def front(self):
        return self.items[0] # 返回队列的第一个元素,但是不移除

    def is_empty(self):
        return self.size() == 0 # 判断队列是否为空

    def size(self):
        return len(self.items) # 返回队列中元素的数量

实例化:

def test001():
    q = PriorityQueue()
    q.enqueue(Person('张三', 20), 1)
    q.enqueue(Person('李四', 21), 2)
    q.enqueue(Person('王五', 22), 1)
    print(q.size()) # 3
    print(q.dequeue().data.name, q.dequeue().data.age)  # 张三,22 打印22是因为调用过dequeue移除了张三这个对象
    q.enqueue(Person('lucy', 21), 1)
    print(q.front().data.name, q.front().data.age) # lucy, 21


test001()

3.7链表

3.7.1单向链表

class Node(): # 用于表示链表中的节点,两个属性,一个是数据,一个是下一个节点的引用
    def __init__(self, data, next=None):
        self.data = data
        self.next = next

class Link(): # 用于实现链表;head:表示头节点;count:表示链表中节点的数量
    def __init__(self):
        self.head = None
        self.count = 0

    def is_empty(self):
        return self.count == 0 # 判断节点是否为空

    def size(self):
        return self.count # 返回链表中节点的数量

    def append(self, data):
        n1 = Node(data)  # 把传入的数据封装为一个Node节点对象
        # 如果是空链表,直接把self(链表对象)的head指向n1
        if self.head is None:
            self.head = n1
        else:
            # 循环找到最后一个节点,将其next属性指向n1
            current = self.head
            while current.next is not None:  # 检验节点是否为空
                current = current.next  # 不为空,则将下个节点赋值给current
            current.next = n1  # while循环中current.next为空,跳出循环,将n1赋值给current.next
        self.count += 1

    def indexof(self, element): # 用于找到指定元素在链表中的索引
        index = 0
        current = self.head
        while current is not None:
            if current.data == element:  # 如果找到了element
                return index  # 则返回index索引
            else:  # 没找到
                current = current.next  # 节点后移
                index += 1  # 同时索引自增
        return -1  # while循环完,也没找到element,此时current为最后一个节点,返回-1

    def insert_into(self, index, data):
        if index < 0 or index > self.count:  # 判断index是否合法
            return
        else:
            n1 = Node(data)
            # 1.如果插入的是头部
            if index == 0:
                n1.next = self.head
                self.head = n1
            else:
                current = self.head
                position = 0
                while position < index:
                    current = current.next
                    position += 1
                # current变量对应的节点就是下标为index的节点
                n1.next = current.next
                current.next = n1
            self.count += 1

    def removeAt(self, position): # 该方法用于移除特定位置的节点
        # 排除越界
        if position < 0 or position >= self.count:
            return
        else:
            # 1.移除的是头部节点
            if position == 0:
                self.head = self.head.next
            else:
                current = self.head
                index = 0
                while index < position - 1:
                    current = current.next
                    index += 1
                current.next = current.next.next
                self.count -= 1

    def remove(self, el): # 用于移除链表中指定元素的节点,需要和indexof和removeAt方法配合使用
        index = self.indexof(el)
        return self.removeAt(index)

实例化

def test001():
    l1 = Link()
    print(f"链表大小: {l1.size()}")  # 初始链表大小
    print(f"链表是否为空: {l1.is_empty()}")  # 链表是否为空
    l1.append(100)
    l1.append(300)
    l1.append(400)
    l1.append(500)
    print(f"链表大小: {l1.size()}")  # 添加节点后链表大小
    l1.insert_into(0, 200)
    print(f"链表大小: {l1.size()}")  # 插入节点后链表大小

    # 返回链表的所有元素
    elements = []
    current = l1.head
    while current is not None:
        elements.append(current.data)
        current = current.next
    return elements

elements = test001()
print(f"链表中的元素: {elements}") 

#链表大小: 0
链表是否为空: True
链表大小: 4
链表大小: 5
链表中的元素: [200, 100, 300, 400, 500]

3.7.2双向链表

class Node(): # 定义链表节点,有数据、前节点引用、后节点引用三个属性
    def __init__(self,data):
        self.data = data
        self.next = None
        self.prev = None
class DoubleLink(): # 实现双向链表,头节点,尾节点,数量三个属性
    def __init__(self):
        self.head = None
        self.tail = None
        self.count = 0

    def append(self,data): # 用于在链表末尾添加一个新的节点
        if self.count == 0:
            n1 = Node(data)
            self.head = n1
            self.tail = n1
        else:
            n1 = Node(data)
            current = self.tail
            self.tail = n1
            self.tail.prev = current
            current.next = self.tail
        self.count+=1

    def append2first(self,data): # 用于在链表头部增加一个新的节点
        n1 = Node(data)
        current = self.head
        self.head = n1
        self.head.next = current
        current.prev = self.head

    def is_empty(self): # 判断链表是否为空
        return self.count == 0

    def size(self): # 返回节点数量
        return self.count

    def indexOf(self,element): # 用于查找指定元素在链表中的索引
        #1.定义变量保存信息
        current = self.head
        index = 0
        #2.查找正确的信息
        while current:
            if current.data == element:
                return index
            index+=1
            current = current.next
        #3.来到这个位置, 说明没有找到, 则返回-1
        return -1

    def insert_into(self,index,data): # 在指定位置插入一个新的节点
        if index < 0 or index>self.count: # 首先判断索引是否合法
            return
        #1.插入尾部
        if self.count == 0:
            self.append(data)
        #2.插入头部
        elif index ==0:
            self.append2first(data)
        #3.插入中间
        else:
            n1 = Node(data)
            current = self.head
            position = 0
            while position<index:
                current = current.next
                position += 1

            one = current.prev
            two = current
            n1.next = two
            one.next = n1
            two.prev = n1
            n1.prev = one
        self.count += 1

    def removeAt(self,position): # 用于移除链表中指定位置的节点
        if self.size ==0 or position<0 or position>=self.count: # 判断是否越界
            return
        else:
            #1.移除的是头部节点
            if position == 0:
                if self.count==1:
                    self.head = None
                    self.tail = None
                else:
                    self.head = self.head.next
                    self.head.prev = None
            #2.移除的是尾部节点
            elif position == self.count-1:
                if self.count==1:
                    self.head = None
                    self.tail = None
                else:
                    self.tail = self.tail.prev
                    self.tail.next = None
            else:
                # position
                current = self.head
                index = 0
                while index<position-1:
                    current = current.next
                    index+=1
                current.next = current.next.next
                current.next.prev = current# current.next已经改变了
            self.count-=1

    def indexof(self,element): # 查找指定元素在链表中的索引
        index = 0
        current = self.head
        while current is not None:
            if current.data == element:
                return index
            else:
                current = current.next
                index +=1
        return -1
    def remove(self,element): # 移除链表中指定元素的节点
        index = self.indexOf(element)
        self.removeAt(index)
    def get_head(self): # 返回链表头结点数据
        return self.head.data if self.head else None
    def get_tail(self): # 返回链表尾节点数据
        return self.tail.data

3.8二叉搜索树

        首先,什么是树?

树通常有一个根. 连接着根的是树干

树干到上面之后会进行分叉成树枝, 树枝还会分叉成更小的树枝

在树枝的最后是叶子

        然后我们把树抽象出来

专家们对树的结构进行了抽象, 发现树可以模拟生活中的很多场景

例如某公司的组织架构

 红楼梦的家谱

 我们再抽象成数据结构

 

树的优点

  • 我们之前已经学习了多种数据结构来保存数据, 为什么要使用树结构来保存数据呢?

    • 树结构和数组/链表/哈希表的对比有什么优点呢?

  • 数组:

    • 优点:

      • 数组的主要优点是根据下标值访问效率会很高.

      • 但是如果我们希望根据元素来查找对应的位置呢?

      • 比较好的方式是先对数组进行排序, 再进行二分查找.

    • 缺点:

      • 需要先对数组进行排序, 生成有序数组, 才能提高查找效率.

      • 另外数组在插入和删除数据时, 需要有大量的位移操作(插入到首位或者中间位置的时候), 效率很低.

  • 链表:

    • 优点:

      • 链表的插入和删除操作效率都很高.

    • 缺点:

      • 查找效率很低, 需要从头开始依次访问链表中的每个数据项, 直到找到.

      • 而且即使插入和删除操作效率很高, 但是如果要插入和删除中间位置的数据, 还是需要重头先找到对应的数据.

  • 树结构:

    • 我们不能说树结构比其他结构都要好, 因为每种数据结构都有自己特定的应用场景.

    • 但是树确实也综合了上面的数据结构的优点(当然优点不足于盖过其他数据结构), 并且也弥补了上面数据结构的缺点.

    • 而且为了模拟某些场景, 我们使用树结构会更加方便. 比如文件的目录结构.

树的术语

  • 在描述树的各个部分的时候有很多术语.

    • 为了让介绍的内容更容易理解, 需要知道一些树的术语.

    • 不过大部分术语都与真实世界的树相关, 或者和家庭关系相关(如父节点和子节点), 所以它们比较容易理解.

    • 我们先来看一下树的结构

  • 树的定义:

    • 树(Tree): n(n≥0)个结点构成的有限集合。

      • 当n=0时,称为空树;

      • 对于任一棵非空树(n> 0),它具备以下性质:

      • 树中有一个称为“根(Root)”的特殊结点,用 root 表示;

      • 其余结点可分为m(m>0)个互不相交的有限集T1,T2,... ,Tm,其中每个集合本身又是一棵树,称为原来树的“子树(SubTree)”

    • 注意:

      • 子树之间不可以相交

      • 除了根结点外,每个结点有且仅有一个父结点;

      • 一棵N个结点的树有N-1条边。

  • 树的术语:

    • 1.结点的度(Degree):结点的子树个数.

    • 2.树的度:树的所有结点中最大的度数. (树的度通常为结点的个数N-1)

    • 3.叶结点(Leaf):度为0的结点. (也称为叶子结点)

    • 4.父结点(Parent):有子树的结点是其子树的根结点的父结点

    • 5.子结点(Child):若A结点是B结点的父结点,则称B结点是A结点的子结点;子结点也称孩子结点。

    • 6.兄弟结点(Sibling):具有同一父结点的各结点彼此是兄弟结点。

    • 7.路径和路径长度:从结点n1到nk的路径为一个结点序列n1 , n2,… , nk, ni是 ni+1的父结点。路径所包含边的个数为路径的长度。

    • 8.结点的层次(Level):规定根结点在1层,其它任一结点的层数是其父结点的层数加1。

    • 9.树的深度(Depth):树中所有结点中的最大层次是这棵树的深度。

 

什么是二叉搜索树?

  • 二叉搜索树(BST,Binary Search Tree),也称二叉排序树或二叉查找树

  • 二叉搜索树是一颗二叉树, 可以为空;如果不为空,满足以下性质:

    • 非空左子树的所有键值小于其根结点的键值。

    • 非空右子树的所有键值大于其根结点的键值。

    • 左、右子树本身也都是二叉搜索树。

  • 下面哪些是二叉搜索树, 哪些不是?

 

  • 二叉搜索树的特点:

    • 二叉搜索树的特点就是相对较小的值总是保存在左结点上, 相对较大的值总是保存在右结点上.

    • 那么利用这个特点, 我们可以做什么事情呢?

    • 查找效率非常高, 这也是二叉搜索树中, 搜索的来源.

 

很长。。。

# 创建结点类
class Node:
    def __init__(self, key):
        self.key = key
        self.left = None
        self.right = None
#创建BinarySearchTree
class BinarySearchTree:
    def __init__(self):
      self.root = None  # 保存根的属性

  # 向树中插入数据
    def insert(self, key):
      # 1.根据key创建对应的node
      newNode = Node(key)
      # 2.判断根结点是否有值
      if self.root == None:
          self.root = newNode
      else:
          self.insertNode(self.root, newNode)

    def insertNode(self, node, newNode):
      # 1.准备向左子树插入数据
      if newNode.key < node.key:
          if (node.left == None):
              # 1.1.node的左子树上没有内容
              node.left = newNode
          else:
              # 1.2.node的左子树上已经有了内容
              self.insertNode(node.left, newNode)
      # 2.准备向右子树插入数据
      else:
          if node.right == None:
              # 2.1.node的右子树上没有内容
              node.right = newNode
          else:
              # 2.2.node的右子树上有内容
              self.insertNode(node.right, newNode)

  # 先序遍历
    def preOrderTraversal(self, handler):
      self.preOrderTranversalNode(self.root, handler)

    def preOrderTranversalNode(self, node, handler):
      if node is not None:
          # 1.打印当前经过的节点
          handler(node.key)
          # 2.遍历所有的左子树
          self.preOrderTranversalNode(node.left, handler)
          # 3.遍历所有的右子树
          self.preOrderTranversalNode(node.right, handler)

  # 中序遍历
    def inOrderTraversal(self, handler):
      self.inOrderTraversalNode(self.root, handler)

    def inOrderTraversalNode(self, node, handler):
      if node is not None:
          # 1.遍历所有的左子树
          self.inOrderTraversalNode(node.left, handler)
          # 2.打印当前经过的节点
          handler(node.key)
          # 3.遍历所有的右子树
          self.inOrderTraversalNode(node.right, handler)

  # 后序遍历
    def postOrderTraversal(self, handler):
      self.postOrderTraversalNode(self.root, handler)

    def postOrderTraversalNode(self, node, handler):
      if node is not None:
          # 1.遍历所有的左子树
          self.postOrderTraversalNode(node.left, handler)
          # 2.遍历所有的右子树
          self.postOrderTraversalNode(node.right, handler)
          # 3.打印当前经过的节点
          handler(node.key)

  # 获取最小值
    def min(self):
      node = self.root
      while node.left is not None:
          node = node.left
      return node.key

  # 获取最大值
    def max(self):
      node = self.root
      while node.right is not None:
          node = node.right
      return node.key

  # 搜搜特定的值
    def search(self, key):
      return self.searchNode(self.root, key)

    def searchNode(self, node, key):
        # 1.如果传入的node为None那么, 那么就退出递归
        if node is None:
            return False
        # 2.判断node节点的值和传入的key大小
        if node.key > key:  # 2.1.传入的key较小, 向左边继续查找
            return self.searchNode(node.left, key)
        elif node.key < key:  # 2.2.传入的key较大, 向右边继续查找
            return self.searchNode(node.right, key)
        else:  # 2.3.相同, 说明找到了key
            return True

    # 找后继的方法
    def getSuccessor(self, delNode):
        # 1.使用变量保存临时的节点
        successorParent = delNode
        successor = delNode
        current = delNode.right  # 要从右子树开始找
        # 2.寻找节点
        while current is not None:
            successorParent = successor
            successor = current
            current = current.left
        # 3.如果是删除图中15的情况, 还需要如下代码
        if successor != delNode.right:
            successorParent.left = successor.right
            successor.right = delNode.right
        return successor

    # 删除结点
    def remove(self, key):
        # 1.定义临时保存的变量
        current = self.root
        parent = None
        isLeftChild = True

        # 2.开始查找节点
        while current.key != key:
            parent = current
            if key < current.key:
                isLeftChild = True
                current = current.left
            else:
                isLeftChild = False
                current = current.right
            # 如果发现current已经指向None, 那么说明没有找到要删除的数据
            if current is None:
                return False
        # 3.找到了开始删除
        # 3.1删除的结点是叶结点
        if current.left is None and current.right is None:
            if current == self.root:
                self.root = None
            elif isLeftChild:
                parent.left = None
            else:
                parent.right = None
        # 3.2删除有一个子节点的节点
        elif current.right is None:
            if current == self.root:
                self.root = current.left
            elif isLeftChild:
                parent.left = current.left
            else:
                parent.right = current.left
        elif current.left is None:
            if current == self.root:
                self.root = current.right
            elif isLeftChild:
                parent.left = current.right
            else:
                parent.right = current.right

        # 3.3删除有两个子节点的节点
        else:
            # 3.3.1.获取后继节点
            successor = self.getSuccessor(current)
            # 3.3.2. 判断是否是根节点
            if current == self.root:
                self.root = successor
            elif isLeftChild:
                parent.left = successor
            else:
                parent.right = successor
            # 3.3.3.将删除节点的左子树赋值给successor
            successor.left = current.left

        # 4.删除完毕返回True
        return True
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值