• python拓展4 数据结构


    内容:

    1.数组

    2.链表

    3.字典

    4.二叉树(搜索树)

    5.set集合实现

    1.数组

    数组在python中是以列表的形式存在,基本上每一个语言中都有数组形式的数据结构存在

    数组一般存储在连续的一块内存,数组存取元素时间是 O(1),插入、删除是 O(n),另外可以用数组实现栈和队列,栈:先进后出,队列:先进先出

    另外python list中有两个部件:

    • 数组 存储数据在链表中的地址
    • 链表 实际存储数据

    列表:

     1 lt = [1, 2, 3, 4, 5, 5]
     2 
     3 # 存取
     4 print(lt[0])
     5 lt[1] = 666
     6 print(lt)
     7 
     8 # 插入元素
     9 lt.insert(0, 333)
    10 print(lt)
    11 
    12 # 删除元素
    13 # 按值删除:
    14 lt.remove(5)
    15 print(lt)
    16 # 按索引删除:
    17 lt.pop(0)
    18 print(lt)
    19 del lt[0]
    20 print(lt)

    用python中的list相关操作实现栈和列表如下:

     1 # encoding: utf-8
     2 # __author__ = "wyb"
     3 # date: 2018/9/28
     4 
     5 
     6 class Stack(object):
     7     def __init__(self):
     8         self.lt = []
     9 
    10     def empty(self):
    11         """
    12         判断栈是否为空
    13         :return:
    14         """
    15         return len(self.lt) == 0
    16 
    17     def top(self):
    18         """
    19         查看栈顶的对象,但不移除
    20         :return:
    21         """
    22         if not self.empty():
    23             return self.lt[-1]
    24         return None
    25     
    26     def push(self, obj):
    27         """
    28         把对象压入栈顶
    29         :return:
    30         """
    31         self.lt.append(obj)
    32 
    33     def pop(self):
    34         """
    35         移除栈顶对象,并返回该对象的值
    36         :return:
    37         """
    38         if not self.empty():
    39             return self.lt.pop()
    40         return None
    41 
    42     def search(self, obj):
    43         """
    44         返回对象在栈中的位置,以1为基数
    45         :param obj:
    46         :return:
    47         """
    48         if not self.empty():
    49             return self.lt.index(obj) + 1
    50         return -1
    51 
    52 
    53 class Queue(object):
    54     def __init__(self):
    55         self.lt = []
    56 
    57     def empty(self):
    58         """
    59         判断队列是否为空
    60         :return:
    61         """
    62         return len(self.lt) == 0
    63     
    64     def first(self):
    65         """
    66         查看队首的对象,但不移除
    67         :return:
    68         """
    69         if not self.empty():
    70             return self.lt[0]
    71         return None
    72 
    73     def enqueue(self, obj):
    74         """
    75         将指定元素加入队列的尾部
    76         :param obj:
    77         :return:
    78         """
    79         self.lt.append(obj)
    80 
    81     def dequeue(self):
    82         """
    83         移除队首对象,并返回该对象的值
    84         :return:
    85         """
    86         if not self.empty():
    87             return self.lt.pop(0)
    88         return None
    89 
    90     def search(self, obj):
    91         """
    92         返回对象在队列中的位置,以1为基数
    93         :param obj:
    94         :return:
    95         """
    96         if not self.empty():
    97             return self.lt.index(obj) + 1
    98         return -1

    用python list实现python中的set:

     1 # encoding: utf-8
     2 # __author__ = "wyb"
     3 # date: 2018/9/29
     4 
     5 
     6 class Set(object):
     7     def __init__(self, *args):
     8         self.table_size = 10007
     9         self.data = [0] * self.table_size
    10         for i in args:
    11             self.add(i)
    12 
    13     def __repr__(self):
    14         """
    15         调用str及输出的魔法方法
    16         :return:
    17         """
    18         lt = set()
    19         for i in range(0, len(self.data)):
    20             if self.data[i] != 0:
    21                 item = self.data[i]
    22                 lt.add(item[0])
    23         return str(lt)
    24 
    25     def __eq__(self, other):
    26         """
    27         判断相等的魔法方法
    28         :param other:
    29         :return:
    30         """
    31         if type(other) == type(self):
    32             return str(self.data) == str(other.data)
    33         else:
    34             return False
    35 
    36     def remove(self, x):
    37         index = self._index(x)
    38         self.data[index] = 0
    39 
    40     def _index(self, obj):
    41         index = hash(obj) % self.table_size
    42         return index
    43 
    44     def _insert_at_index(self, index, key):
    45         v = self.data[index]
    46         if v == 0:
    47             self.data[index] = [key]
    48         else:
    49             return False
    50 
    51     def add(self, key):
    52         # 先计算出下标
    53         index = self._index(key)
    54         # 在下标处插入元素
    55         self._insert_at_index(index, key)
    56 
    57         # for i in range(0, len(self.data)):
    58         #     if self.data[i] == x:
    59         #         return False
    60         # self.data.append(x)
    61 
    62     def has(self, key):
    63         index = self._index(key)
    64         # 取元素
    65         v = self.data[index]
    66         if isinstance(v, list):
    67             if v[0] == key:
    68                 return True
    69         return False
    70 
    71         # for i in range(0, len(self.data)):
    72         #     if self.data[i] == x:
    73         #         return True
    74         # return False
    75 
    76 
    77 def testSet():
    78     a = Set(1, 2, 2, 3, 4, 4)
    79     b = Set(1, 2, 2, 3, 4)
    80     c = Set(1, 3, 4, 2)
    81     d = Set(2, 3)
    82     assert (str(a) == '{1, 2, 3, 4}')
    83     print(a, b, c, d)
    84     assert (a == b)
    85     assert (a == c)
    86     assert (a != d)
    87     assert (a.has(1) is True)
    88     a.remove(1)
    89     assert (a.has(1) is False)
    90     a.add(1)      
    91     assert (a.has(1) is True)
    92 
    93 
    94 if __name__ == '__main__':
    95     testSet()

    2.链表

    我们可以将链表比作手拉手的盒子,一个盒子只能访问左右手的盒子

    以下标方式读取元素的时间是 O(n),插入、删除是 O(1),栈和队列可以用链表实现,栈:先进后出,队列:先进先出

    链表简单实现:

     1 # encoding: utf-8
     2 # __author__ = "wyb"
     3 # date: 2018/9/27
     4 
     5 
     6 class Node():
     7     def __init__(self, element=None):
     8         self.e = element
     9         self.next = None
    10 
    11 
    12 def append(node, element):
    13     """
    14     append: 添加一个元素到末尾
    15     :param node: 是一个 Node 实例
    16     :param element: 任意类型的元素
    17     """
    18     n = node
    19     while n.next is not None:
    20         n = n.next
    21     # n 现在是最后一个元素
    22     new_node = Node(element)
    23     n.next = new_node
    24 
    25 
    26 def prepend(head_node, element):
    27     """
    28     prepend: 添加一个元素到开头
    29     :param head_node: 头元素
    30     :param element: 任意类型的元素
    31     :return:
    32     """
    33     n = Node(element)
    34     n.next = head_node.next
    35     head_node.next = n
    36 
    37 
    38 def pop(head_node):
    39     """
    40     pop是stack的两个操作之一
    41     push 入栈
    42     pop 出栈
    43     prepend + pop 就实现了 队列 的 入队(enqueue)和出队(dequeue)操作
    44     append + pop 就实现了 栈 的 入栈(push) 和 出栈(pop)操作
    45     :param head_node: 头部节点
    46     :return:
    47     """
    48     tail = head_node
    49     while tail.next is not None:
    50         tail = tail.next
    51     # 现在 tail 是最后一个元素了
    52     n = head_node
    53     while n.next is not tail:
    54         n = n.next
    55     # 现在 n 是 tail 之前的元素了
    56     n.next = None
    57     return tail.e
    58 
    59 
    60 def log_list(node):
    61     n = node
    62     s = ''
    63     while n is not None:
    64         s += (str(n.e) + ' > ')
    65         n = n.next
    66     print(s[0: -2])
    67 
    68 
    69 head = Node()
    70 n1 = Node(111)
    71 n2 = Node(222)
    72 n3 = Node(333)
    73 n1.next = n2
    74 n2.next = n3
    75 
    76 head.next = n1
    77 
    78 log_list(n1)
    79 append(n1, 'gua')
    80 log_list(n1)
    81 prepend(head, 'hello')
    82 log_list(head)
    83 print('pop head: ', pop(head))
    84 log_list(head)

    链表封装成类:

      1 # encoding: utf-8
      2 # __author__ = "wyb"
      3 # date: 2018/9/27
      4 
      5 
      6 # 节点类
      7 class Node(object):
      8     def __init__(self, element=-1):
      9         self.element = element
     10         self.next = None
     11 
     12 
     13 # 链表类
     14 class LinkedList(object):
     15     def __init__(self):
     16         self.head = None
     17 
     18     def is_empty(self):
     19         """
     20         判断链表是否为空
     21         :return:
     22         """
     23         return self.head is None
     24 
     25     def length(self):
     26         """
     27         获得链表长度(包含head)
     28         :return:
     29         """
     30         index = 0
     31         node = self.head
     32         while node is not None:
     33             index += 1
     34             node = node.next
     35         return index
     36 
     37     def find(self, element):
     38         """
     39         查找元素
     40         :param element: 元素值
     41         :return:
     42         """
     43         node = self.head
     44         while node is not None:
     45             if node.element == element:
     46                 return node
     47             node = node.next
     48         return None
     49 
     50     def _node_at_index(self, index):
     51         """
     52         返回某个节点
     53         :param index: 索引 -> 从0开始 0是head
     54         :return:
     55         """
     56         i = 0
     57         node = self.head
     58         while node is not None:
     59             if i == index:
     60                 return node
     61             node = node.next
     62             i += 1
     63         return None
     64 
     65     def element_at_index(self, index):
     66         """
     67         返回某个节点的值
     68         :param index: 索引 -> 从0开始 0是head
     69         :return:
     70         """
     71         node = self._node_at_index(index)
     72         return node.element
     73 
     74     def first_object(self):
     75         """
     76         返回第一个节点 -> head
     77         :return:
     78         """
     79         return self._node_at_index(0)
     80 
     81     def last_object(self):
     82         """
     83         返回最后一个节点
     84         :return:
     85         """
     86         i = 0
     87         while self._node_at_index(i) is not None:
     88             i += 1
     89         return self._node_at_index(i - 1)
     90 
     91     def insert_before_index(self, position, element):
     92         """
     93         在节点之前插入元素
     94         :param position: 节点位置
     95         :param element: 元素值
     96         :return:
     97         """
     98         insert_node = Node(element)
     99         # 错误情况判断:
    100         if position == 0:
    101             print("不能在head之前插入元素")
    102             return False
    103         if self._node_at_index(position) is None:
    104             print("节点顺序超了!请输入正确的节点顺序!")
    105             return False
    106         node = self._node_at_index(position - 1)
    107         # 插入元素
    108         insert_node.next = node.next
    109         node.next = insert_node
    110 
    111     def insert_after_index(self, position, element):
    112         """
    113         在节点之后插入元素
    114         :param position: 节点位置
    115         :param element: 元素值
    116         :return:
    117         """
    118         insert_node = Node(element)
    119         node = self._node_at_index(position)
    120         # 错误情况判断:
    121         if node is None:
    122             print("节点顺序超了!请输入正确的节点顺序!")
    123             return False
    124         # 在节点之后插入元素
    125         insert_node.next = node.next
    126         node.next = insert_node
    127 
    128     def append(self, element):
    129         """
    130         在最后插入节点
    131         :param element: 节点值
    132         :return:
    133         """
    134         node = Node(element)
    135         if self.head is None:
    136             self.head.next = node
    137         else:
    138             last_node = self.last_object()
    139             last_node.next = node
    140             node.front = last_node
    141 
    142     def prepend(self, element):
    143         """
    144         在开头插入节点
    145         :param element: 节点值
    146         :return:
    147         """
    148         node = Node(element)
    149         node.next = self.head.next
    150         self.head.next = node
    151 
    152     def pop(self):
    153         """
    154         删除最后一个节点
    155         :return:
    156         """
    157         tail = self.first_object()
    158         while tail.next is not None:
    159             tail = tail.next
    160         # 现在 tail 是最后一个元素了
    161         n = self.first_object()
    162         while n.next is not tail:
    163             n = n.next
    164         # 现在 n 是 tail 之前的元素了
    165         n.next = None
    166         return tail.element
    167 
    168     def log_list(self, msg=""):
    169         """
    170         输出链表
    171         :param msg: 输出链表之前显示的信息
    172         :return:
    173         """
    174         n = self.head.next
    175         s = msg + ''
    176         while n is not None:
    177             s += (str(n.element) + ' > ')
    178             n = n.next
    179         print(s[0: -2])
    180 
    181 
    182 # 测试链表初始化及输出链表:
    183 def test_log():
    184     head = Node(0)
    185     n1 = Node(1)
    186     n2 = Node(2)
    187     n3 = Node(3)
    188     lt = LinkedList()
    189     lt.head = head
    190     head.next = n1
    191     n1.next = n2
    192     n2.next = n3
    193     lt.log_list("输出链表: ")
    194     return lt
    195 
    196 
    197 # 测试链表判空及链表长度:
    198 def test_empty_length(lt):
    199     if lt.is_empty() is True:
    200         print("链表为空")
    201         return None
    202     else:
    203         length = lt.length()
    204         print("链表不为空, 链表长度为: ", length)
    205         return length
    206 
    207 
    208 # 测试find
    209 def test_find(lt):
    210     if lt.find(5) is None:
    211         print("链表中不存在5")
    212     else:
    213         print("链表中存在5")
    214         node = lt.find(5)
    215         return node
    216 
    217     if lt.find(3) is None:
    218         print("链表中不存在3")
    219     else:
    220         print("链表中存在3")
    221         node = lt.find(3)
    222         return node
    223 
    224 
    225 # 测试element_at_index
    226 def test_element_at_index(lt):
    227     print(lt.element_at_index(0))
    228     print(lt.element_at_index(1))
    229     print(lt.element_at_index(2))
    230     print(lt.element_at_index(3))
    231 
    232 
    233 # 测试first_obj和last_obj
    234 def test_first_last(lt):
    235     print(lt.first_object().element)
    236     print(lt.last_object().element)
    237 
    238 
    239 # 测试插入
    240 def test_insert(lt):
    241     lt.insert_before_index(0, "在节点0之前插入")
    242     lt.log_list()
    243     lt.insert_before_index(1, "在节点1之前插入")
    244     lt.log_list()
    245     lt.insert_after_index(0, "在节点0之后插入")
    246     lt.log_list()
    247     lt.insert_after_index(2, "在节点2之后插入")
    248     lt.log_list()
    249     lt.append("在最后插入节点")
    250     lt.log_list()
    251     lt.prepend("在开头插入节点")
    252     lt.log_list()
    253 
    254 
    255 # 测试pop
    256 def test_pop(lt):
    257     lt.pop()
    258     lt.log_list("删除最后一个元素: ")
    259 
    260 
    261 # 单元测试
    262 def test():
    263     linked_list = test_log()
    264 
    265     # 测试空链表:
    266     # test_empty_length(LinkedList())
    267 
    268     # 测试非空链表:
    269     # test_empty_length(linked_list)
    270 
    271     # 测试find
    272     # test_find(linked_list)
    273 
    274     # 测试element_at_index
    275     # test_element_at_index(linked_list)
    276 
    277     # 测试first_obj和last_obj
    278     # test_first_last(linked_list)
    279 
    280     # 测试insert
    281     # test_insert(linked_list)
    282 
    283     # 测试pop
    284     # test_pop(linked_list)
    285 
    286 
    287 if __name__ == '__main__':
    288     test()
    View Code

    另外,关于栈和队列的实现:

    上述链表实现中prepend + pop 就实现了 队列 的 入队(enqueue)和出队(dequeue)操作,append + pop 就实现了 栈 的 入栈(push) 和 出栈(pop)操作

     1 # encoding: utf-8
     2 # __author__ = "wyb"
     3 # date: 2018/9/28
     4 
     5 """
     6  数据结构的核心是,一个结构只有特定的操作,可以实现特定的功能
     7 
     8  栈的特点是「先进后出」,一般有这几个操作
     9 # push 将一个元素存入栈中
    10 # pop  将一个元素从栈中取出,并在栈中删除它
    11 
    12 # top  将一个元素从栈中取出
    13 # is_empty 查看栈是否是空的
    14 
    15 """
    16 
    17 
    18 # Node类是一个节点,有两个属性,一个存储元素,一个存储指向另一个节点的引用
    19 class Node:
    20     def __init__(self, element=None, next=None):
    21         self.element = element
    22         self.next = next
    23 
    24     # 这个函数是会在print的时候被自动调用,就是把这个Node显示出来
    25     def __repr__(self):
    26         return str(self.element)
    27 
    28 
    29 class Stack:
    30     # 初始化函数,自动被调用
    31     # 初始化Stack()类的时候,它有一个head属性,值是一个空的Node
    32     def __init__(self):
    33         self.head = Node()
    34 
    35     # 如果head的next属性为空,则说明栈是空的
    36     def is_empty(self):
    37         return self.head.next is None
    38 
    39     # 创建一个node,并让它指向当前head.next指向的元素,再把head.next指向它
    40     def push(self, element):
    41         self.head.next = Node(element, self.head.next)
    42 
    43     # 取出head.next指向的元素,如果栈不是空的,就让head.next指向node.next,这样node就不在栈中了
    44     def pop(self):
    45         node = self.head.next
    46         if not self.is_empty():
    47             self.head.next = node.next
    48         return node
    49 
    50     # head.next就是栈里面第一个元素
    51     def top(self):
    52         return self.head.next
    53 
    54 
    55 # 测试函数
    56 def test():
    57     s = Stack()
    58 
    59     s.push(1)
    60     s.push(2)
    61     s.push(3)
    62     s.push(4)
    63 
    64     print(s.pop())
    65     print(s.pop())
    66     print(s.pop())
    67     print(s.pop())
    68 
    69 
    70 if __name__ == '__main__':
    71     # 运行测试函数
    72     test()
    链表实现栈
     1 # encoding: utf-8
     2 # __author__ = "wyb"
     3 # date: 2018/9/28
     4 
     5 
     6 """
     7 队列的特点是「先进先出」,一般有这几个操作
     8 
     9 # enqueue 将一个元素存入队列中
    10 # dequeue 将一个元素从队列中取出,并在队列中删除它
    11 
    12 # empty 查看栈是否是空的
    13 
    14 可以把队列看做排队,银行叫号机就是队列,先取号的先入队,叫号的时候也就先出队
    15 """
    16 
    17 
    18 # Node类是一个节点,有两个属性,一个存储元素,一个存储指向另一个节点的引用
    19 class Node:
    20     def __init__(self, element=None, next=None):
    21         self.element = element
    22         self.next = next
    23 
    24     # 这个函数是会在print的时候被自动调用,就是把这个Node显示出来
    25     def __repr__(self):
    26         return str(self.element)
    27 
    28 
    29 class Queue:
    30     # 初始化函数,自动被调用
    31     # 初始化Queue()类的时候,它有2个属性,分别指向头尾
    32     def __init__(self):
    33         self.head = Node()
    34         self.tail = self.head
    35 
    36     # 如果head的next属性为空,则说明队列是空的
    37     def empty(self):
    38         return self.head.next is None
    39 
    40     # 创建一个node
    41     # 让tail.next指向它
    42     # 让tail指向它,tail现在就是新的队尾了
    43     def enqueue(self, element):
    44         n = Node(element)
    45         self.tail.next = n
    46         self.tail = n
    47 
    48     # 取出head.next指向的元素,如果队列不是空的,就让head.next指向node.next,这样node就不在队列中了
    49     def dequeue(self):
    50         node = self.head.next
    51         if not self.empty():
    52             self.head.next = node.next
    53         return node
    54 
    55 
    56 # 测试函数
    57 def test():
    58     q = Queue()
    59 
    60     q.enqueue(1)
    61     q.enqueue(2)
    62     q.enqueue(3)
    63     q.enqueue(4)
    64 
    65     print(q.dequeue())
    66     print(q.dequeue())
    67     print(q.dequeue())
    68     print(q.dequeue())
    69 
    70 
    71 if __name__ == '__main__':
    72     # 运行测试函数
    73     test()
    链表实现队列

    3.字典(哈希表、对象、Map)

    python中的字典把字符串转为数字作为下标存储到数组中,字符串转化为数字的算法是 O(1),所以字典的存取操作都是 O(1)

    除非对数据有顺序要求,否则字典永远是最佳选择

    字符串转化为数字的算法:

    • 确定数据规模,这样可以确定容器数组的大小 Size
    • 把字符当作 N 进制数字得到结果
    • eg:'gua' 被视为 g * 1 + u * 10 + a * 100 得到结果 n,n % Size 作为字符串在数组中的下标(通常 Size 会选一个 素数)
    • 当下标冲突时,有标准的解决碰撞方法(链接法)

    实现字典(哈希表):

      1 class HashTable(object):
      2     def __init__(self):
      3         # table 是用来存储数据的数组
      4         # 先让它有 10007 个格子好了
      5         # 上课的时候说过, 这个尺寸最好选素数
      6         # 这样可以得到更为合理的下标分布
      7         self.table_size = 10007
      8         self.table = [0] * self.table_size
      9 
     10     # 这个魔法方法是用来实现 in  not in 语法的
     11     def __contains__(self, item):
     12         return self.has_key(item)
     13 
     14     def has_key(self, key):
     15         """
     16         检查一个 key 是否存在, 时间很短, 是 O(1)
     17         如果用 list 来存储, 需要遍历, 时间是 O(n)
     18         """
     19         index = self._index(key)
     20         # 取元素
     21         v = self.table[index]
     22         if isinstance(v, list):
     23             # 检查是否包含我们要找的 key
     24             for kv in v:
     25                 if kv[0] == key:
     26                     return True
     27         # 如果得到的是 int 0 说明没找到, 返回 False
     28         # 如果得到的是 list 但是遍历结果没有我们要找的 key 也是没找到
     29         return False
     30 
     31     def _insert_at_index(self, index, key, value):
     32         # 检查下标处是否是第一次插入数据
     33         v = self.table[index]
     34         data = [key, value]
     35         # 也可以用这个判断 if v == 0:
     36         if isinstance(v, int):
     37             # 如果是第一次, 得到的是 int 0
     38             # 那么就插入一个 list 来存, 以后相同 key 的元素都放这里面
     39             # 注意我们把 key value 作为一个数组保存进去了, 这是因为
     40             # 会出现相同 hash 值的 key
     41             # 这时候就需要比较原始信息来找到相应的数据
     42             self.table[index] = [data]
     43         else:
     44             # 如果不是, 得到的会是 list, 直接 append
     45             self.table[index].append(data)
     46 
     47     def add(self, key, value):
     48         """
     49         add 函数往 hashtable 中加入一对元素
     50         我们先只支持字符串当 key
     51         """
     52         # 先计算出下标
     53         index = self._index(key)
     54         # 在下标处插入元素
     55         self._insert_at_index(index, key, value)
     56 
     57     def get(self, key, default_value=None):
     58         """
     59         这个和 dict 的 get 函数一样
     60         """
     61         index = self._index(key)
     62         # 取元素
     63         v = self.table[index]
     64         if isinstance(v, list):
     65             # 检查是否包含我们要找的 key
     66             for kv in v:
     67                 if kv[0] == key:
     68                     return kv[1]
     69         # 如果得到的是 int 0 说明没找到, 返回 default_value
     70         # 如果得到的是 list 但是遍历结果没有我们要找的 key 也是没找到
     71         return default_value
     72 
     73     def _index(self, key):
     74         # 先计算出下标
     75         return self._hash(key) % self.table_size
     76 
     77     def _hash(self, s):
     78         """
     79         下划线开始的函数被我们视为私有函数
     80         但实际上还是可以在外部调用, 这只是一个给自己看的标记
     81         """
     82         n = 1
     83         f = 1
     84         for i in s:
     85             n += ord(i) * f
     86             f *= 10
     87         return n
     88 
     89 
     90 def test():
     91     import uuid
     92     names = [
     93         'gua',
     94         'xiao',
     95         'name',
     96         'web',
     97         'python',
     98     ]
     99     ht = HashTable()
    100     for key in names:
    101         value = uuid.uuid4()
    102         ht.add(key, value)
    103         print('add 元素', key, value)
    104     for key in names:
    105         v = ht.get(key)
    106         print('get 元素', key, v)
    107     print('魔法方法', 'gua' in ht)
    108 
    109 
    110 if __name__ == '__main__':
    111     test()

    4.二叉树(搜索树)

    二叉树(又叫搜索树):

     1 # encoding: utf-8
     2 # __author__ = "wyb"
     3 # date: 2018/9/28
     4 
     5 
     6 class Tree(object):
     7     def __init__(self, element=None):
     8         self.element = element
     9         self.left = None
    10         self.right = None
    11 
    12     def traversal(self):
    13         """
    14         树的遍历, 是一个递归操作
    15         """
    16         print(self.element)     # 前序遍历
    17         if self.left is not None:
    18             self.left.traversal()
    19         # print(self.element)   # 中序遍历
    20         if self.right is not None:
    21             self.right.traversal()
    22         # print(self.element)   # 后序遍历
    23 
    24     def reverse(self):
    25         """
    26         翻转二叉树
    27         :return:
    28         """
    29         self.left, self.right = self.right, self.left
    30         if self.left is not None:
    31             self.left.reverse()
    32         if self.right is not None:
    33             self.right.reverse()
    34 
    35 
    36 def test():
    37     # 手动构建二叉树
    38     t = Tree(0)
    39     left = Tree(1)
    40     right = Tree(2)
    41     t.left = left
    42     t.right = right
    43     # 遍历
    44     t.traversal()
    45 
    46 
    47 if __name__ == '__main__':
    48     test()

    5.set集合实现

    (1)题目要求

     1 # 作业一:
     2 # 写一个 set 的类, 无序且元素不重复,内部使用数组来存储元素,具有以下成员函数
     3 # 1. remove ,删除元素
     4 # 2. add, 增加元素
     5 # 3. has,判断元素是否存在
     6 # 形式如下:
     7 # class Set(object):
     8 #     def __init__(self, *args)
     9 #         self.data = []
    10 #         # ...
    11 #     def remove(self, x):
    12 #         pass
    13 #     def add(self, x):
    14 #         pass
    15 #     def has(self, x):
    16 #         pass
    17 #
    18 #
    19 # 作业二:
    20 # 在作业一的基础上,在Set类里增加 __repr__  和 __eq__ 两个成员函数。
    21 # 并通过附带 testSet() 函数的测试。
    22 # 形式如下:
    23 # class Set(object):
    24 #     # ...
    25 #     def __init__(self, *args)
    26 #         self.data = []
    27 #
    28 #     def __repr__(self):
    29 #         pass
    30 #
    31 #     def __eq__(self, other):
    32 #         pass
    33 #
    34 #     def remove(self, x):
    35 #         pass
    36 #     def add(self, x):
    37 #         pass
    38 #     def has(self, x):
    39 #         pass
    40 #
    41 # def testSet():
    42 #     a = Set(1, 2, 2, 3, 4, 4)
    43 #     b = Set(1, 2, 2, 3, 4)
    44 #     c = Set(1, 3, 4, 2)
    45 #     d = Set(2, 3)
    46 #     assert (str(a) == '{1, 2, 3, 4}')
    47 #     print(a, b, c, d)
    48 #     assert (a == b)
    49 #     assert (a == c)
    50 #     assert (a != d)
    51 #     assert (a.has(1) == True)
    52 #     a.remove(1)
    53 #     assert (a.has(1) == False)
    54 #     a.add(1)
    55 #     assert (a.has(1) == True)
    56 #
    57 #
    58 # 作业三:
    59 # 参考第17课板书 hash_table 的代码,写一个类 Set,实现时间复杂度为O(1) 的 add,remove 函数 。
    60 # 形式如下:
    61 # class Set(object):
    62 #     # ...
    63 #     def add(self, x):
    64 #         pass
    65 #
    66 #     def remove(self, x):
    67 #         pass

    (2)实现

  • 相关阅读:
    Mysql 一次性备份导出/导入恢复所有数据库
    MySQL数据备份之mysqldump使用
    mysql数据库误删除后的数据恢复操作说明
    Qt的模态对话框和非模态对话框 经常使用setAttribute (Qt::WA_DeleteOnClose)
    Qt paintEvent绘制窗体 注意Qt::WA_PaintOutsidePaintEvent 只是适用于X11,其他系统均无效
    Building PySide on Microsoft Windows
    浅议Delphi中的Windows API调用(举的两个例子分别是String和API,都不错,挺具有代表性)
    Qt多线程学习-用例子来理解多线程
    Nutch之简介与安装
    RPC框架实现
  • 原文地址:https://www.cnblogs.com/wyb666/p/9710849.html
Copyright © 2020-2023  润新知