https://blog.csdn.net/weixin_45912307/article/details/115792813
根据线性表的实际存储方式,分为两种实现模型:
1. 单向链表(单链表) : 它的每个节点包含两个域,一个信息域(元素域)和一个连接域,这个链接指向链表中的下一个节点,而最后一个节点的链接则指向一个空值。
2. 单链表的操作
3. python实现单向链表
class Node(object):
def __init__(self, elem):
"""
:param elem: 表元素域
next:下一结点链接域
cursor(cur):游标
"""
self.elem = elem
# 定义next指向空
self.next = None
class SingleLinkList(object):
"""
单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一一个节点,而最后-个节点的链接域则指向一个空值。
表元素域elem用来存放具体的数据。
链接域next用来存放下一个节点的位置(python中的标识)
变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节点。
"""
def __init__(self, node=None):
self.__head = node # node.elem node.next
def is_empty(self):
"""链表是否为空 """
return self.__head is None
def length(self):
"""链表长度"""
# cur游标,用来移动遍历节点
cur = self.__head
count = 0
while cur is not None:
count += 1
cur = cur.next
# count 记录数量
return count
def travel(self):
"""遍历整个链表"""
cur = self.__head
while cur is not None:
print(cur.elem, end=' ')
cur = cur.next
def add(self, item):
"""链表头部添加元素:头插法"""
node = Node(item)
node.next = self.__head
self.__head = node
def append(self, item):
"""链表尾部添加元素:尾插法"""
node = Node(item)
# 下一结点链接域不为空
if self.is_empty():
self.__head = node
else:
cur = self.__head
while cur.next is not None:
cur = cur.next
cur.next = node
def insert(self, pos, item):
"""
pos: pos从0开始
pre:指定节点前一节点,相当于游标
node:插入的指定节点
指定位置添加元素
"""
# if pos<=0 头插法
if pos <= 0:
self.add(item)
# elif pos>(self.length()-1) 尾插法
elif pos > (self.length() - 1):
self.append(item)
# else 插入法
else:
pre = self.__head
count = 0
# 当循环退出后,pre指向pos-1
while count < (pos - 1):
count += 1
pre = pre.next
node = Node(item)
node.next = pre.next
pre.next = node
def remove(self, item):
"""删除元素"""
# 考虑删除头部、尾部、中间节点
cur = self.__head
pre = None
while cur is not None:
if cur.elem == item:
# 先判断是否是头节点
if cur == self.__head:
self.__head = cur.next
else:
pre.next = cur.next
break
else:
pre = cur
cur = cur.next
def search(self, item):
"""查找节点是否存在"""
# 1. 创建游标
cur = self.__head
# 2. 遍历游标
while cur is not None:
# 3. cur.elem = item
if cur.elem == item:
return True
else:
cur = cur.next
return False
if __name__ == '__main__':
ll = SingleLinkList()
ll.is_empty()
l1 = ll.length()
print(l1)
ll.append(55)
ll.is_empty()
l2 = ll.length()
print(l2)
ll.append(2)
ll.add(8)
ll.append(3)
ll.append(4)
ll.append(5)
# 55 1 8 2 3 4
ll.insert(-1, 9) # 9 8 55 2 1 8 2345
ll.insert(2, 100) # 9 8 100 55 2 1 8 2345
ll.travel()
1. 双向链表定义: 一种更复杂的链表是“双向链表"或“双面链表"。每个节点有两个链接: 一个指向前一个节点,当此节点为第
一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。
2.双向链表操作:
3.python实现双向循环链表
class Node(object):
def __init__(self, elem):
"""
:param elem: 表元素域
next:下一结点链接域
cursor(cur):游标
"""
self.elem = elem
# 定义next指向空
self.next = None
# 定义next指向空
self.prev = None
class DoubleLinkList(object):
"""
一种更复杂的链表是“双向链表"或“双面链表"。每个节点有两个链接: 一个指向前一个节点,当此节点为第
一个节点时,指向空值;而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。
"""
def __init__(self, node=None):
self._head = node # node.elem node.next
def is_empty(self):
"""链表是否为空 """
return self._head is None
def length(self):
"""链表长度"""
# cur游标,用来移动遍历节点
cur = self._head
count = 0
while cur is not None:
count += 1
cur = cur.next
# count 记录数量
return count
def travel(self):
"""遍历整个链表"""
cur = self._head
while cur is not None:
print(cur.elem, end=' ')
cur = cur.next
def add(self, item):
"""链表头部添加元素:头插法"""
node = Node(item)
# node的next指向_head
node.next = self._head
# _head指向新节点
self._head = node
node.next.prev = node
def append(self, item):
"""链表尾部添加元素:尾插法"""
node = Node(item)
# 下一结点链接域不为空
if self.is_empty():
self._head = node
else:
cur = self._head
while cur.next is not None:
cur = cur.next
cur.next = node
node.prev = cur
def insert(self, pos, item):
"""
pos: pos从0开始
pre:指定节点前一节点,相当于游标
node:插入的指定节点
指定位置添加元素
"""
# if pos<=0 头插法
if pos <= 0:
self.add(item)
# elif pos>(self.length()-1) 尾插法
elif pos > (self.length() - 1):
self.append(item)
# else 插入法
else:
cur = self._head
count = 0
# 当循环退出后,cur指向pos
while count < pos:
count += 1
cur = cur.next
# 当循环退出后,cur指向pos位置
node = Node(item)
# 方式1:
node.next = cur
node.prev = cur.prev
cur.prev.next = node
cur.prev = node
# 方式2:
# node.next = cur
# node.prev = cur.prev
# cur.prev = node
# node.prev.next = node
def remove(self, item):
"""删除元素"""
# 考虑删除头部、尾部、中间节点
cur = self._head
while cur is not None:
if cur.elem == item:
# 先判断是否是头节点
if cur == self._head:
self._head = cur.next
if cur.next: # 判断链表表是否只有一个节点
cur.next.prev = None
else:
cur.prev.next = cur.next
if cur.next: # 判断链表是否是最后一个节点
cur.next.prev = cur.prev
break
else:
cur = cur.next
def search(self, item):
"""查找节点是否存在"""
# 1. 创建游标
cur = self._head
# 2. 遍历游标
while cur is not None:
# 3. cur.elem = item
if cur.elem == item:
return True
else:
cur = cur.next
return False
if __name__ == '__main__':
DLL = DoubleLinkList()
DLL.is_empty()
l1 = DLL.length()
print(l1)
DLL.append(55)
DLL.is_empty()
l2 = DLL.length()
print(l2)
DLL.append(2)
DLL.add(8)
DLL.append(3)
DLL.append(4)
DLL.append(5)
# 55 1 8 2 3 4
DLL.insert(-1, 9) # 9 8 55 2 1 8 2345
DLL.insert(2, 100) # 9 8 100 55 2 1 8 2345
DLL.travel()
1. 定义: 单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为none,而是指向链表的头节点
2. 单向循环链表操作:
3.python实现单向循环链表
class Node(object):
def __init__(self, elem):
"""
:param elem: 表元素域
next:下一结点链接域
cursor(cur):游标
"""
self.elem = elem
# 定义next指向空
self.next = None
class SingleCircularLinkList(object):
"""
单向循环链表:单链表的一个变形是单向循环链表,链表中最后一个节点的next域不再为none,而是指向链表的头节点
"""
def __init__(self, node=None):
self.__head = node # node.elem node.next
if node:
node.next = node
def is_empty(self):
"""链表是否为空 """
return self.__head is None
def length(self):
"""链表长度"""
if self.is_empty():
return 0
# cur游标,用来移动遍历节点
cur = self.__head
count = 1
while cur.next != self.__head:
count += 1
cur = cur.next
# count 记录数量
return count
def travel(self):
"""遍历整个链表"""
if self.is_empty():
return
cur = self.__head
while cur.next != self.__head:
print(cur.elem, end=' ')
cur = cur.next
# 退出循环,cur指向尾结点,但尾节点的元素未打印
print(cur.elem)
def add(self, item):
"""链表头部添加元素:头插法"""
node = Node(item)
if self.is_empty():
self.__head = node
node.next = node
else:
cur = self.__head
while cur.next != self.__head:
cur = cur.next
# 退出循环,cur指向尾结点
node.next = self.__head
self.__head = node
# 方式1:cur.next = node
cur.next = self.__head # 方式2
def append(self, item):
"""链表尾部添加元素:尾插法"""
node = Node(item)
# 下一结点链接域不为空
if self.is_empty():
self.__head = node
node.next = node
else:
cur = self.__head
while cur.next != self.__head:
cur = cur.next
# 方式1:
# node.next = cur.next
# cur.next = node
# 方式2:
cur.next = node
node.next = self.__head
def insert(self, pos, item):
"""
pos: pos从0开始
pre:指定节点前一节点,相当于游标
node:插入的指定节点
指定位置添加元素
"""
# if pos<=0 头插法
if pos <= 0:
self.add(item)
# elif pos>(self.length()-1) 尾插法
elif pos > (self.length() - 1):
self.append(item)
# else 插入法
else:
pre = self.__head
count = 0
# 当循环退出后,pre指向pos-1
while count < (pos - 1):
count += 1
pre = pre.next
node = Node(item)
node.next = pre.next
pre.next = node
def remove(self, item):
"""删除元素"""
# 考虑删除头部、尾部、中间节点
if self.is_empty():
return
cur = self.__head
pre = None
while cur.next != self.__head:
if cur.elem == item:
# 先判断是否是头节点
if cur == self.__head:
# 找到尾节点
rear = self.__head
while rear.next != self.__head:
rear = rear.next
self.__head = cur.next
rear.next = self.__head
else:
# 中间节点
pre.next = cur.next
return
else:
pre = cur
cur = cur.next
# 退出循环,cur指向尾结点
if cur.elem == item:
if cur == self.__head:
# 链表只有一个节点
self.__head = None
else:
pre.next = cur.next
def search(self, item):
"""查找节点是否存在"""
if self.is_empty():
return False
# 1. 创建游标
cur = self.__head
# 2. 遍历游标
while cur.next != self.__head:
# 3. cur.elem = item
if cur.elem == item:
return True
else:
cur = cur.next
# 对于最后一个元素或只有一个元素
if cur.elem == item:
return True
return False
if __name__ == '__main__':
ll = SingleCircularLinkList()
ll.is_empty()
l1 = ll.length()
print(l1)
ll.append(55)
ll.is_empty()
l2 = ll.length()
print(l2)
ll.append(2)
ll.add(8)
ll.append(3)
ll.append(4)
ll.append(5)
# 55 1 8 2 3 4
ll.insert(-1,9) # 9 8 55 2 1 8 2345
ll.insert(2,100) #9 8 100 55 2 1 8 2345
ll.travel()
1.栈的定义(LIFO:last in First Out): 栈是一种操作受限制的线性表,将允许进行插入、删除、访问元素的一端称为栈顶,另一端称为栈底。
2.栈支持的操作:
3.python实现堆栈
class Stack():
"""
栈方式1:假设列表的尾部是栈的顶端。当栈增长时(即进行push操作), 新的元素会被添加到列表的尾部。pop操作同样会修改这一端。
将允许进行插入、删除的一端称为栈顶,另一端称为栈底。
"""
# 创建一个空栈
def __init__(self):
self.__list = []
# 检查栈是否为空:判断是否等于一个空列表
def isEmpty(self):
return self.__list == []
# return not self.__list
# 统计栈的长度
def size(self):
return len(self.__list)
# 返回栈顶元素
def peek(self):
# return self.__list[len(self.__list)-1]
if self.__list:
return self.__list[-1]
else:
return None
# 入栈(把列表尾部假设为栈顶)
def push(self, item):
self.__list.append(item)
# 出栈
def pop(self):
return self.__list.pop()
class Stack2:
"""
栈方式2:选择将列表头部作为顶端,必须用pop方法和insert方法显式地访问下标为0的元素,即列表中的第一个元素;
"""
def __init__(self):
self.__list = []
def isEmpty(self):
"""判断栈是否为空"""
# return self.__list == []
return not self.__list
def size(self):
"""返回栈的元素个数"""
return len(self.__list)
# 入栈
def push(self, item):
"""添加一个新的元素item到栈顶"""
self.__list.insert(0, item)
# 出栈
def pop(self):
return self.__list.pop(0)
def peek(self):
"""返回栈顶元素"""
if self.__list:
return self.__list[0]
else:
return None
if __name__ == '__main__':
s = Stack2()
print(s.isEmpty())
s.push('a')
s.push('b')
s.push('小明')
s.push('c')
print(s.size())
print(s.pop())
print(s.pop())
print(s.pop())
print(s.pop())
1. 队列定义(FIFO:First In First Out): 队列是一种特殊的线性表,只允许在表的前端进行删除操作,而在表的后端进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头;
2. 队列支持的操作:
3.python实现队列:
class Queue1:
"""
队列方式1:假设列表头部为队头:append向队列尾部添加元素,pop(0)移除队列头部元素
"""
def __init__(self):
self.__list = []
def isEmpty(self):
return self.__list == []
def size(self):
return len(self.__list)
# 队尾插入元素
def enqueue(self, item):
self.__list.append(item)
# 队头删除元素
def dequeue(self):
return self.__list.pop(0)
class Queue2:
"""
假设列表头部(位置0)为队尾:insert向队列尾部添加元素O(n),pop移除队列头部元素O(1)
"""
def __init__(self):
self.__list = []
def isEmpty(self):
return self.__list == []
def size(self):
return len(self.__list)
# 队列尾部插入元素
def enqueue(self, item):
self.__list.insert(0, item)
# 把队头删除的元素返回
def dequeue(self):
return self.__list.pop()
if __name__ == '__main__':
q = Queue2()
print(q.isEmpty())
q.enqueue(10)
q.enqueue(100)
q.enqueue(1000)
q.enqueue(10000)
print(q.size())
print(q.dequeue()) # 10
print(q.dequeue()) # 100
print(q.dequeue()) # 1000
print(q.dequeue()) # 10000
print(q.size())
1. 双端队列定义: 具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。双端队列可以在队列任意一端入队和出队。
3.双端队列支持的操作:
4.python实现双端队列:
# -- encoding: utf-8 --
# @time: 2021/4/18 11:49
# @Author: jsonLiu
# @Email: [email protected]
# @file: deque
# 双端队列
"""
- Deque()创建一个空的双端队列。它不需要参数,且会返回一个空的双端队列。
- addFront(item)将一个元素添加到双端队列的前端。它接受一个元素作为参数,没有返回值
- addRear (item)将一个元素添加到双端队列的后端。它接受一个元素作为参数,没有返回值。
- popFront()从双端队列的前端移除一个元素。它不需要参数,且会返回一个元素,并修改双端队列的内容。
- popRear()从双端队列的后端移除一个元素。它不需要参数,且会返回一个元素,并修改双端队列的内容。
- isEmpty()检查双端队列是否为空。它不需要参数,且会返回一个布尔值。
- size()返回双端队列中元素的数目。它不需要参数,且会返回一个整数。
"""
class Deque1:
"""假设双端队列的后端是列表位置0处"""
def __init__(self):
self.__list = []
def isEmpty(self):
# return self.__list == []
return not self.__list
def size(self):
return len(self.__list)
def add_front(self, item):
"""添加到双端队列前端"""
self.__list.append(item)
def add_rear(self, item):
"""添加到双端队列后端"""
self.__list.insert(0, item)
def pop_front(self):
"""从双端队列的前端移除一个元素"""
return self.__list.pop(len(self.__list) - 1)
# return self.__list.pop()
def pop_rear(self):
"""双端队列的后端移除一个元素"""
return self.__list.pop(0)
class Deque2:
"""假设双端队列的前端是列表位置0处"""
def __init__(self):
self.__list = []
def isEmpty(self):
# return self.__list == []
return not self.__list
def size(self):
return len(self.__list)
def add_front(self, item):
"""添加到双端队列前端"""
self.__list.insert(0, item)
def add_rear(self, item):
"""添加到双端队列后端"""
self.__list.append(item)
def pop_front(self):
"""从双端队列的前端移除一个元素"""
return self.__list.pop(0)
def pop_rear(self):
"""双端队列的后端移除一个元素"""
# return self.__list.pop()
return self.__list.pop(len(self.__list) - 1)
if __name__ == '__main__':
d = Deque2()
# d = Deque1()
print(d.isEmpty()) # True
d.add_rear(4)
d.add_rear(3)
d.add_front(2)
d.add_front(1)
print(d.size()) # 4
d.add_rear(5)
print(d.pop_rear())
print(d.pop_front())
1.冒泡排序:
2.选择排序
3.插入排序:
4.快速排序
5.希尔排序 (插入排序改进版)
6.归并排序
# -- encoding: utf-8 --
# @time: 2021/4/18 12:30
# @Author: jsonLiu
# @Email: [email protected]
# @file: sort_algorithm
# 1. 冒泡排序 最坏时间复杂度n^2,最优时间复杂度O(n)
def bubble_sort(alist):
if isinstance(alist, tuple):
alist = list(alist)
for i in range(len(alist) - 1): # len(alist)-1比较的轮数
count = 0
for j in range(len(alist) - 1 - i): # len(alist)-1-i每轮需要比较的次数
if alist[j] > alist[j + 1]:
alist[j + 1], alist[j] = alist[j], alist[j + 1]
count += 1
if 0 == count: # 当为有序序列时,时间复杂度为O(n)
return
# 2. 选择排序 最优时间复杂度/最坏时间复杂度 n^2
def selection_sort(alist):
# 假设位置0为最小值
n = len(alist)
for j in range(n - 1): # j:0~n-2
min_index = j
for i in range(j + 1, n):
if alist[i] < alist[min_index]:
min_index = i
alist[j], alist[min_index] = alist[min_index], alist[j]
# 3. 插入排序:最坏时间复杂度O(n^2) 最优时间复杂度O(n)
def insert_sort(alist):
n = len(alist)
# 外层循环:从右边的无序序列中取出多少个元素执行这样的过程
for j in range(1, n):
i = j
# 内层循环:执行从右边的无序序列中取出第一个元素,即i位置的元素,然后将其插入到前面的正确位置
while i > 0:
if alist[i - 1] > alist[i]:
alist[i], alist[i - 1] = alist[i - 1], alist[i]
i -= 1
else:
break
# 4. 快速排序 最优时间复杂度nlogn 最坏时间复杂度n^2
def quick_sort(alist, first, last):
if first >= last:
return
mid_value = alist(first)
low = first
high = last
while low < high:
while low < high and alist[high] >= mid_value:
high -= 1
alist[low] = alist[high]
while low < high and alist[low] < mid_value:
low += 1
alist[high] = alist[low]
# 从顺序退出时,low == high
alist[low] = mid_value
# 对low左边列表执行快速排序
quick_sort(alist, first, low - 1)
# 对low右边列表排序
quick_sort(alist, low + 1, last)
# 5.希尔排序
def shell_sort(alist):
n = len(alist)
gap = n // 2
while gap > 0:
# 与普通插入算法区别就是gap步长
for j in range(gap, n):
i = j
while i > 0:
if alist[i] < alist[i - gap]:
alist[i], alist[i - gap] = alist[i - gap], alist[i]
i -= gap
else:
break
gap //= 2 # gap除以2,缩短步长
# 6.归并算法
def merge_sort(alist):
n = len(alist)
if n <= 1:
return alist
mid = n // 2
# left 采用归并排序后形成的有序的新的列表
left_li = merge_sort(alist[:mid])
# right 采用归并排序后形成的有序的新的列表
right_li = merge_sort(alist[mid:])
# 将两个有序的子序列合并为一个新的整体
# merge_sort(left,right)
left_pointer, right_pointer = 0, 0
new_l = []
while left_pointer < len(left_li) and right_pointer < len(right_li):
if left_li[left_pointer] < right_li[right_pointer]:
new_l.append(left_li[left_pointer])
left_pointer += 1
else:
new_l.append(right_li[right_pointer])
right_pointer += 1
# 反之左边或右边列表最后一个值没有append
new_l += left_li[left_pointer:]
new_l += right_li[right_pointer:]
return new_l
if __name__ == '__main__':
# s = 8,5,10,9,2
# l = bubble_sort(s)
# print(l)
# s = [17,20,93,54,77,31,44]
# l = selection_sort(s)
# print(l)
# s = [20, 17, 93, 54, 77, 31, 44]
# insert_sort(s)
# print(s)
# s = [20, 17, 93, 54, 77, 31, 44, 54]
# insert_sort(s)
# print(s)
# s = [20, 17, 93, 54, 77, 31, 44, 54]
# shell_sort(s)
# print(s)
l = [20, 17, 93, 54, 77, 31, 44, 54]
print(l)
new_l = merge_sort(l)
print(new_l)
1.无序列表顺序搜索: 从列表中的第一个元素开始,沿着默认的顺序逐个查看,知道找到目标元素或者查完列表。如果查完列表后仍没有找到目标元素,则说明目标元素不在列表中。
2.有序列表顺序搜索: 假设列表中的元素按升序排列。如果存在目标元素,那么它出现在n个位置中任意一个位置的可能性仍然一样大,因此比较次数与在无序列表中相同。如果不存在目标元素,那么搜索效率就会提高;
def UnsequentialSearch(ulist, item):
"""
这个函数接受列表与目标元素作为参数, 并返回一个表示目标元素是否存在的布尔值。布尔型变量found的初始值为False, 如果找到目标元素,就将它的值改为Tru
"""
pos = 0
found = False
while pos < len(ulist) and not found:
if ulist[pos] == item:
found = True
else:
pos += 1
return found
def OrderedListSequentialSearch(ulist,item):
pos = 0
found = False
stop = False
while pos < len(ulist) and not found and not stop:
if ulist[pos] == item:
found = True
else:
if ulist[pos] > item:
stop = True
else:
pos = pos+1
return found
if __name__ == '__main__':
# ret = UnsequentialSearch([1, 3, 10, 5, 8], 7)
# print(ret)
ret = OrderedListSequentialSearch([1, 3, 5, 7, 10], 6)
print(ret)
1.二分查找定义
2.python实现二分查找:
"""
应用前提:在一个含有n个元素的有序序列中定位目标值 时间复杂度:O(logn)
该算法维持两个参数low和high,这样可使所有候选条目的索引位于low和high之间。首先, low=0和high=n-1。然后我们比较目标值和中间值候选项,即索引项[mid]的数据。
mid =L(low + high)/2 ]考虑以下三种情况:
- 如果目标值等于[mid]的数据, 然后找到正在寻找的值,则查找成功并且终止。
- 如果目标值< [mid] 的数据, 对前半部分序列重复这一过程,即索引的范围从low到mid-1.
- 如果目标值> [mid] 的数据,对后半部分序列重复这一过程,即索的范围从mid+1到high。
- 如果low >high,说明索引范围[low, high]为空,则查找不成功。该算法被称为二分查找
"""
def binary_search(alist, item):
"""非递归"""
first = 0
last = len(alist) - 1
found = False
while first <= last and not found:
mid = (first + last) // 2
if alist[mid] == item:
found = True
else:
if item < alist[mid]:
last = mid - 1
else:
first = mid + 1
return found
def binary_search_recursion(alist, item):
if len(alist) > 0:
mid = len(alist) // 2
if alist[mid] == item:
return True
elif item < alist[mid]:
return binary_search_recursion(alist[:mid], item)
else:
return binary_search_recursion(alist[mid + 1:], item)
return False
if __name__ == '__main__':
ret = binary_search_recursion([17, 20, 26, 31, 44, 54, 55, 65, 77, 69], 26)
print(ret)
ret = binary_search([17, 20, 26, 31, 44, 54, 55, 65, 77, 69], 68)
print(ret)
class Map(object):
def __init__(self,size=11):
self.size = size
self.__slots = [None] * self.size
self.__data = [None] * self.size
def put(self, key, val):
hashvalue = self.hashfunction(key, len(self.__slots))
if self.__slots[hashvalue] == None:
self.__slots[hashvalue] = key
self.__data[hashvalue] = val
else:
if self.__slots[hashvalue] == key:
self.__data[hashvalue] = val
else:
nextslot = self.rehash(hashvalue, len(self.__slots))
while self.__slots[nextslot] != None and self.__slots[nextslot] != key:
nextslot = self.rehash(nextslot, len(self.__slots))
if self.__slots[nextslot] == None:
self.__slots[nextslot] = key
self.__data[nextslot] = val
else:
self.__data[nextslot] = val
def get(self, key):
startslot = self.hashfunction(key, len(self.__slots))
data = None
stop = False
found = False
position = startslot
while self.__slots[position] != None and \
not found and not stop:
if self.__slots[position] == key:
found = True
data = self.__data[position]
else:
position = self.rehash(position, len(self.__slots))
if position == startslot:
stop = True
return data
def delete(self,key):
pass
def __getitem__(self, key):
return self.get(key)
def __setitem__(self, key, val):
self.put(key, val)
def __delitem__(self, key):
self.delete(key)
def len(self):
pass
def hashfunction(self, key, size):
return key % size
def rehash(self, oldhash, size):
return (oldhash + 1) % size
树(tree)是一种抽象数据类型〈ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集食。它是由n (n>=1)个有限节点组成一个具有层次关系的集合。把它叫做"树"是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点∶
BinaryTree()
创建一个二叉树实例。getLeftChild()
返回当前节点的左子节点所对应的二叉树。getRightChild()
返回当前节点的右子节点所对应的二叉树。setRootval(val)
在当前节点中存储参数val中的对象。getRootval()
返回当前节点存储的对象。insertLeft(val)
新建一棵二叉树,并将其作为当前节点的左子节点。insertRight (val)
新建一棵二叉树,并将其作为当前节点的右子节点。class Node(object):
def __init__(self,item):
self.elem = item
self.rchild = None
self.lchild = None
class BinaryTree(object):
def __init__(self):
self.root = None
def add(self,item):
# 添加元素操作
node = Node(item)
if self.root == None:
self.root = node
return
queue = [self.root]
while queue:
cur_node = queue.pop(0)
if cur_node.lchild is None:
cur_node.lchild = node
return
else: # 左子节点存在则append追加
queue.append(cur_node.lchild)
if cur_node.rchild is None:
cur_node.rchild = node
return
else:
queue.append(cur_node.rchild)
# 广度遍历(层次遍历)
def breadth_travel(self):
queue = [self.root]
if self.root is None:
return
while queue:
cur_node = queue.pop(0)
print(cur_node.elem,end=" ")
if cur_node.lchild is not None:
queue.append(cur_node.lchild)
if cur_node.rchild is not None:
queue.append(cur_node.rchild)
def preorder(self,node):
"""先序遍历"""
if node is None:
return
print(node.elem,end=" ")
self.preorder(node.lchild)
self.preorder(node.rchild)
def inorder(self,node):
"""中序遍历"""
if node is None:
return
self.inorder(node.lchild)
print(node.elem, end=" ")
self.inorder(node.rchild)
def postorder(self,node):
"""后序遍历"""
if node is None:
return
self.postorder(node.lchild)
self.postorder(node.rchild)
print(node.elem, end=" ")
if __name__ == '__main__':
tree = BinaryTree()
tree.add(1)
tree.add(3)
tree.add(5)
tree.add(7)
tree.add(9)
tree.add(11)
tree.breadth_travel() # 层次:1 3 5 7 9 11
print("\n")
tree.preorder(tree.root) # 先序 1 3 7 9 5 11
print("\n")
tree.inorder(tree.root) # 中序:7 3 9 1 11 5
print("\n")
tree.postorder(tree.root) # 后序:7 9 3 11 5 1