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)实现

 

posted @ 2018-09-27 12:07  woz333333  阅读(165)  评论(0编辑  收藏  举报