队列、栈:
图:
散列表:
树:
Redis 提供列表、字符串、集合等等几种常用数据结构,但是对于每种数据结构,底层的存储方式都至少有两种,以便于根据存储数据的实际情况使用合适的存储方式
对于任何数据结构,其基本操作无非遍历 + 访问,再具体一点就是:增删查改
各种数据结构的遍历 + 访问无非两种形式:线性的和非线性
先刷二叉树,先刷二叉树,先刷二叉树!
先刷二叉树,先刷二叉树,先刷二叉树!!!!!!!!!!!!!
# 数组
li = [1, 2, 3]
for i in li:
print(i)
for i in len(li):
print(li[i])
#append(self, object, /)
li.append(4)
#copy(self, /)
##相当于li2 = li[:]
li2 = li.copy()
#extend(self, iterable, /)
##前者合并可迭代对象
li2.extend(li)
#index(self, value, start=0, stop=9223372036854775807, /)
##通过元素值查找元素下标(元素值,开始坐标=0,结束坐标=无穷大)
li2.index(2,4,7)
#count(self, value, /)
li2.count(1)
#insert(self, index, object, /)
li2.insert(1,7)
#pop(self, index=-1, /)
li2.pop(-2)
#remove(self, value, /)
li2.remove(2)
#reverse(self, /)
li2.reverse()
#sort(self, /, *, key=None, reverse=False)
li2.sort(reverse=True)
#clear(self, /)
li2.clear()
class Node:
def __init__(self,item):
self.item = item
self.next = None
class SingleNode:
def __init__(self):
self._head = None
def is_empty(self):
return self._head is None
def length(self):
count = 0
cur = self._head
while cur is not None:
count += 1
cur = cur.next
return count
def traverse(self):
cur = self._head
while cur is not None:
yield cur.item
cur = cur.next
def appendleft(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,index,item):
if index <= 0:
self.appendleft(item)
elif index >= self.length():
self.append(item)
else:
node = Node(item)
cur = self._head
for i in range(index-1):
cur = cur.next
node.next = cur.next
cur.next = node
def remove(self,item):
cur = self._head
pre = None
while cur is not None:
if cur.item == item:
if pre is None:
self._head = cur.next
else:
pre.next = cur.next
return True
else:
pre = cur
cur = cur.next
return False
def find(self,item):
return item in self.traverse()
ln = SingleNode()
ln.appendleft(2)
ln.appendleft(1)
ln.append(3)
ln.append(4)
ln.insert(-1,0)
ln.insert(100,5)
ln.insert(3,2.333)
ln.remove(2.333)
print(ln.find(2))
print(ln.is_empty())
print(ln.length())
print('===')
for i in ln.traverse():
print(i)
"""
二叉树
"""
class Node(object):
def __init__(self, data=None, left=None, right=None):
self.data = data
self.left = left
self.right = right
def __str__(self):
return str(self.data)
class Tree:
def __init__(self, root=None):
self.root = root
def add(self, item):
node = Node(item)
if self.root is None:
self.root = node
else:
q = [self.root]
while True:
pop_node = q.pop(0)
if pop_node.left is None:
pop_node.left = node
return
elif pop_node.right is None:
pop_node.right = node
return
else:
q.append(pop_node.left)
q.append(pop_node.right)
def get_parent(self, item):
# 找到item的父节点
if self.root.data == item:
return None
q = [self.root]
while q:
pop_node = q.pop(0)
if pop_node.left and pop_node.left.data == item:
return pop_node
elif pop_node.right and pop_node.right.data == item:
return pop_node
else:
if pop_node.left is not None:
q.append(pop_node.left)
if pop_node.right is not None:
q.append(pop_node.right)
return None
def delete(self, item):
'''
从二叉树中删除一个元素
先获取 待删除节点 item 的父节点
如果父节点不为空,
判断 item 的左右子树
如果左子树为空,那么判断 item 是父节点的左孩子,还是右孩子,如果是左孩子,将父节点的左指针指向 item 的右子树,反之将父节点的右指针指向 item 的右子树
如果右子树为空,那么判断 item 是父节点的左孩子,还是右孩子,如果是左孩子,将父节点的左指针指向 item 的左子树,反之将父节点的右指针指向 item 的左子树
如果左右子树均不为空,寻找右子树中的最左叶子节点 x ,将 x 替代要删除的节点。
删除成功,返回 True
删除失败, 返回 False
'''
if self.root is None: # 如果根为空,就什么也不做
return False
parent = self.get_parent(item)
if parent:
del_node = parent.left if parent.left.data == item else parent.right # 待删除节点
if del_node.left is None:
if parent.left.data == item:
parent.left = del_node.right
else:
parent.right = del_node.right
del del_node
return True
elif del_node.right is None:
if parent.left.data == item:
parent.left = del_node.left
else:
parent.right = del_node.left
del del_node
return True
else: # 左右子树都不为空
tmp_pre = del_node
tmp_next = del_node.right
if tmp_next.left is None:
# 替代
tmp_pre.right = tmp_next.right
tmp_next.left = del_node.left
tmp_next.right = del_node.right
else:
while tmp_next.left: # 让tmp指向右子树的最后一个叶子
tmp_pre = tmp_next
tmp_next = tmp_next.left
# 替代
tmp_pre.left = tmp_next.right
tmp_next.left = del_node.left
tmp_next.right = del_node.right
if parent.left.data == item:
parent.left = tmp_next
else:
parent.right = tmp_next
del del_node
return True
else:
return False
def preorder(self, root):
if not root:
return []
result = [root.data]
left_item = self.preorder(root.left)
right_item = self.preorder(root.right)
return result + left_item + right_item
def inorder(self, root):
if not root:
return []
result = [root.data]
left_item = self.inorder(root.left)
right_item = self.inorder(root.right)
return left_item + result + right_item
def postorder(self, root):
if not root:
return []
result = [root.data]
left_item = self.postorder(root.left)
right_item = self.postorder(root.right)
return left_item + right_item + result
def traverse(self):
if self.root is None:
return None
q = [self.root]
res = [self.root.data]
while q != []:
pop_node = q.pop(0)
if pop_node.left is not None:
q.append(pop_node.left)
res.append(pop_node.left.data)
if pop_node.right is not None:
q.append(pop_node.right)
res.append(pop_node.right.data)
return res
if __name__ == '__main__':
t = Tree()
for i in range(10):
t.add(i)
print(t.preorder(t.root))
print(t.inorder(t.root))
print(t.postorder(t.root))
print(t.traverse())