单链表 # 实现单链表 class Node(object): '''定义一个节点''' def __init__(self,data): # 因为每次都需要生成一个节点,写到类里面便于保存 self.data = data # 保存节点的值 self.next = None # 默认将节点的指向为空 # 二元组也可以实现节点 (data,next指针域) ,为了通用性不使用二元组 class DanLianBiao(object): # 定义一个单链表 将节点连接起来 def __init__(self,node = None): # 指向节点 如果没传递则使用 None self._head = node # 定义头节点,指向实例化类对象时传递的节点指向 def is_empty(self): '''链表是否为空''' return self._head == None def length(self): '''查询链表长度''' cur = self._head # cur 为当前指向的指针 count = 0 # 记录长度 while cur != None: # 当前指向不为 None count += 1 # 数量加 1 cur = cur.next # 将指针对节点进行移动 # 如果第一个节点为 None ,依旧是返回 0 return count # 返回节点数量 def travel(self): '''遍历整个链表''' cur = self._head while cur != None: # 如果不为空 则打印数据 print(cur.data) # 打印数据 cur = cur.next # 向下遍历 def add(self,data): '''链表头部添加元素''' node = Node(data) self._head = node # 将节点指向头部 node.next = self._head # 将头部作为节点的下一个元素 def append(self,data): '''链表尾部添加元素''' node = Node(data) # 创建一个节点 # 特殊情况 第一个节点为空 if self.is_empty(): self._head = node # 头节点为 node else: cur = self._head while cur.next != None: cur = cur.next # cur.next.data = node.data # 不需要添加数据 cur.next = node # 添加节点 def insert(self,pos,data): '''指定位置添加元素''' # 如果为零位置 if pos <= 0: self.add(data) # 添加节点 elif pos > (self.length()-1): # 到最后一个元素 self.append(data) # 添加节点 else: node = Node(data) index = 0 cur = self._head while index < pos : # 遍历到 pos 前一个位置 index += 1 cur = cur.next # 不断向下移动 node.next = cur.next # 先和右面元素建立联系 防止与左面元素失联 cur.next = node def remove(self,data): '''删除节点''' cur = self._head pre = None # 设置游标表示前一个游标 while cur != None: if cur.data == data: # 如果 cur 指向的节点为要删除的节点 if cur == self._head: # 如果数据为头节点的数据 self._head = cur.next # 跳过 cur else: # 如果不是头节点 pre.next = cur.next # 跳过 cur 指向的节点 break # 找到数据跳出循环 else: # 如果还没有找到数据 pre = cur cur = cur.next # 向下移动 def search(self,data): '''查找节点是否存在''' cur = self._head # 指向头节点 while cur.next != None: # 如果下一个节点不为空 if cur.data == data: # 如果找到了数据 return True else: cur = cur.next # 继续向下寻找 return False # 没有找到该数据
双链表 # 实现双链表 class Node(object): # 前驱 数据 后继 def __init__(self,data): self.pre = None # 前驱 self.data = self.data # 数据 self.next = None # 后继 class DoubleLianBiao(object): # 定义一个双链表 将节点连接起来 def __init__(self,node = None): # 指向节点 如果没传递则使用 None self._head = node # 定义头节点,指向实例化类对象时传递的节点指向 def is_empty(self): '''链表是否为空''' return self._head is None def length(self): '''查询链表长度''' cur = self._head # cur 为当前指向的指针 count = 0 # 记录长度 while cur != None: # 当前指向不为 None count += 1 # 数量加 1 cur = cur.next # 将指针对节点进行移动 # 如果第一个节点为 None ,依旧是返回 0 return count # 返回节点数量 def travel(self): '''遍历整个链表''' cur = self._head while cur != None: # 如果不为空 则打印数据 print(cur.data,end = " ") # 打印数据 cur = cur.next # 向下遍历 def add(self,data): '''链表头部添加元素''' node = Node(data) # 将节点指向头部 node.next = self._head # 将头部作为节点的下一个元素 self._head = node # 将 node 作为头节点 node.next.pre = node # 牵右手 让 node 后的节点指向node def append(self,data): '''链表尾部添加元素''' node = Node(data) # 创建一个节点 # 特殊情况 第一个节点为空 if self.is_empty(): self._head = node # 头节点为 node else: cur = self._head while cur.next != None: cur = cur.next # cur.next.data = node.data # 不需要添加数据 cur.next = node # 添加节点 node.pre = cur # 连接左面的两只手 def insert(self,pos,data): '''指定位置添加元素''' # 如果为零位置 if pos <= 0: self.add(data) # 添加节点 elif pos > (self.length()-1): # 到最后一个元素 self.append(data) # 添加节点 else: node = Node(data) index = 0 cur = self._head while index < pos : # 遍历到 pos 前一个位置 index += 1 cur = cur.next # 不断向下移动 node.next = cur # 右手:node 连接 当前指向的节点 node.pre = cur.pre # 左手:node 的前一个节点为当前位置的前一个节点 cur.pre.next = node # 左手:当前位置的前一个节点的下一个节点为 node 节点 cur.pre = node # 右手:当前位置的前一个节点 为 node 节点 def remove(self,data): '''删除节点''' cur = self._head # 设置游标表示前一个游标 while cur != None: if cur.data == data: # 如果 cur 指向的节点为要删除的节点 if cur == self._head: # 如果数据为头节点的数据 self._head = cur.next # 跳过 cur if cur.next != None: # 如果只有一个节点,None 没有pre属性 cur.next.pre = None # 删除头节点后 头节点值为 None else: # 如果不是头节点 cur.pre.next = cur.next # 左手:当前节点的前一个节点的后一个节点为当前节点的后一个节点 if cur.next != None: # 查看是否是最后一个节点,None 没有 pre 属性 cur.next.pre = cur.pre # 右手:当前节点的下一个节点的前一个节点为当前节点的前一个节点 break # 找到数据跳出循环 else: # 如果还没有找到数据 cur = cur.next # 向下移动 def search(self,data): '''查找节点是否存在''' cur = self._head # 指向头节点 while cur.next != None: # 如果下一个节点不为空 if cur.data == data: # 如果找到了数据 return True else: cur = cur.next # 继续向下寻找 return False # 没有找到该数据
单向循环链表 # 实现单向循环链表 class Node(object): '''定义一个节点''' def __init__(self,data): # 因为每次都需要生成一个节点,写到类里面便于保存 self.data = data # 保存节点的值 self.next = None # 默认将节点的指向为空 class DanLianBiao_Cycle(object): # 定义一个单向循环链表 将节点连接起来 def __init__(self,node = None): # 指向节点 如果没传递则使用 None self._head = node # 定义头节点,指向实例化类对象时传递的节点指向 if node != None: # 如果传递过来的不是 None # 第一个节点时需要指向自身(不同之处) node.next = node # 指向自己 def is_empty(self): '''链表是否为空''' return self._head == None def length(self): '''查询链表长度''' if self.is_empty(): return 0 count = 1 # 等于1 是因为如果为0 到最后不能够加到足够数目 while cur.next != self._head: count += 1 cur = cur.next return count def travel(self): '''遍历整个链表''' if self.is_empty(): return cur = self._head while cur.next != self._head: print(cur.data) cur = cur.next print(cur.data) # 尾节点的下一个元素为头节点,跳出循环了,打印尾节点数据 def add(self,data): '''链表头部添加元素''' node = Node(data) if self.is_empty(): self._head = node # 头节点指向 node 节点 node.next = node # node 节点的下一个节点还为 node else: cur = self._head # 指定当前节点指向 while cur.next != self._head: # 一直遍历 cur = cur.next # 不断向下 # cur 当前指向最后一个节点 node.next = self._head # 右手:node 的下一个节点为头节点 self._head = node # 让头指针指向 node 节点 cur.next = self._head # 尾指针的下一个节点为更新后的头节点 def append(self,data): '''链表尾部添加元素''' node = Node(data) if self.is_empty(): self._head = node node.next = node else: cur = self._head while cur.next != self._head: cur = cur.next node.next = cur.next # 右手:cur.next 为头节点 # 让 node 作为尾节点指向头节点 cur.next = node # 左手:让当前节点的下一个节点指向 node 节点 def insert(self,pos,data): '''指定位置添加元素''' # 如果为零位置 if pos <= 0: self.add(data) # 添加节点 elif pos > (self.length()-1): # 到最后一个元素 self.append(data) # 添加节点 else: node = Node(data) index = 0 cur = self._head while index < pos : # 遍历到 pos 前一个位置 index += 1 cur = cur.next # 不断向下移动 node.next = cur.next # 先和右面元素建立联系 防止与左面元素失联 cur.next = node def remove(self,data): '''删除节点''' if self.is_empty(): return cur = self._head pre = None # 设置游标表示前一个游标 while cur.next != self._head: if cur.data == data: # 如果 cur 指向的节点为要删除的节点 if cur == self._head: # 如果数据为头节点的数据 rear = self._head # 定义一个可以找到尾节点的指针 while rear.next != self._head: rear = rear.next # 此时 rear 为尾节点 self._head = cur.next # 跳过头节点 rear.next = self._head # 尾节点的下一个元素为头节点的下一个元素 else: # 如果不是头尾节点,是中间节点 pre.next = cur.next # 跳过 cur 指向的节点 return # 找到数据并返回 else: # 如果还没有找到数据 pre = cur cur = cur.next # 向下移动 # cur 当前指向为尾节点 if cur.data == data: if cur == self._head: # 如果只有一个节点,cur 没有改变过 self._head = None else: # 尾部节点为要删除的节点 pre.next = cur.next def search(self,data): '''查找节点是否存在''' if self.is_empty(): return False cur = self._head # 指向头节点 while cur.next != self._head: # 如果下一个节点不为空 if cur.data == data: # 如果找到了数据 return True else: cur = cur.next # 继续向下寻找 # 处理尾部节点 if cur.data == data: return True # 如果找到了元素 return False # 没有找到该数据
栈 class Stack(object): '''创建一个栈''' def __init__(self): self.__lst = [] # 将列表设置为私有,不让外界进行访问 def add(self,data): '''在尾部添加元素''' self.__lst.append(data) def pop(self): '''在尾部取出元素''' return self.__lst.pop() # pop 删除最后一个对象,并返回值 def peek(self): '''返回栈顶元素''' if self.__lst != []: # 如果不为空 return self.__lst[-1] # 返回最后一个元素(后进先出) else: # 栈为空 return None def is_empty(self): '''判断链表是否为空''' return self.__lst == [] # 不要直接返回 self.__lst 会导致外部得到私有成员 def size(self): '''返回栈的元素个数''' return len(self.__lst) # self.__lst 为列表对象,使用 len 获取长度
队列 class Queue(object): '''实现队列''' def __init__(self): self.__lst = [] # 创建一个容器容纳队列成员 def append_data(self,data): # 添加元素 self.__lst.append(data) def pop_headdata(self): # 从头部删除数据 return self.__lst.pop() def is_empty(self): return self.__lst == [] # 判断是否为空 def size(self): # 返回队列长度 return len(self.__lst)
双端队列 class DoubleQueue(object): '''实现双端队列''' def __init__(self): self.__lst = [] # 创建一个容器容纳队列成员 def append_frontdata(self,data): '''在头部添加元素''' self.__lst.insert(0,data) def append_reardata(self,data): '''在尾部添加元素''' self.__lst.append(data) def pop_headdata(self): # 从头部删除数据 return self.__lst.pop(0) def pop_reardata(self): # 在尾部删除数据 return self.__lst.pop() def is_empty(self): return self.__lst == [] # 判断是否为空 def size(self): # 返回队列长度 return len(self.__lst)
二叉树的创建 ''' 树: 每一个结点都有零个或多个子结点 没有父节点的节点称为根节点 每一个非根结点有且只有一个父结点 除了根结点外,每一个子节点可以分为多个不相交的子树 二叉树性质: 在二叉树的第 i 层 最多有 2^(i-1) 个结点 深度为 k 的二叉树最多有 2^k - 1 个结点 叶子结点数为 N0 度数为 2 的结点数为 N2 N0 = N2 + 1 具有 n 个结点的完全二叉树的深度为 log2(n+1) 完全二叉树: 编号为 i 的结点 左孩子 -> 2i 右孩子 -> 2i + 1 左孩子 的 父结点 编号必为 i/2 ''' class Node(object): '''定义一个结点,有左孩子和右孩子''' def __init__(self,data): # 结点数据 self.data = data # 左、右 孩子指向为空 self.lchild = None self.rchild = None class BinaryTree(object): '''定义二叉树''' def __init__(self): # 根结点默认为空 self.root = None def add(self,data): # 添加数据到二叉树中 向最后进行添加数据 # 处理顺序:父结点 左孩子 右孩子 node = Node(data) # 如果为空树 if self.root is None: self.root = node # 空树,加入数据则放在根节点处 return queue = [self.root] # 添加根节点,作为存在该结点的标志 while queue: # 如果 queue 不为空 cur_node = queue.pop(0) # 当前结点指向根节点,取第一个元素 if cur_node.lchild is None : # 如果左结点为空 cur_node.lchild = node return else: # 添加到指针内,证明存在左结点 queue.append(cur_node.lchild) if cur_node.rchild is None: # 如果右结点为空 cur_node.rchild = node return else: # 添加到指针内,证明存在右结点 queue.append(cur_node.rchild)
广度遍历 class Node(object): '''定义一个结点,有左孩子和右孩子''' def __init__(self,data): # 结点数据 self.data = data # 左、右 孩子指向为空 self.lchild = None self.rchild = None class BinaryTree(object): '''定义二叉树''' def __init__(self): # 根结点默认为空 self.root = None def add(self,data): # 添加数据到二叉树中 向最后进行添加数据 # 处理顺序:父结点 左孩子 右孩子 node = Node(data) # 如果为空树 if self.root is None: self.root = node # 空树,加入数据则放在根节点处 return queue = [self.root] # 添加根节点,作为存在该结点的标志 while queue: # 如果 queue 不为空 cur_node = queue.pop(0) # 当前结点指向根节点,取第一个元素 if cur_node.lchild is None : # 如果左结点为空 cur_node.lchild = node return else: # 添加到指针内,证明存在左结点 queue.append(cur_node.lchild) if cur_node.rchild is None: # 如果右结点为空 cur_node.rchild = node return else: # 添加到指针内,证明存在右结点 queue.append(cur_node.rchild) def bread_travel(self): '''广度遍历''' if self.root is None: # 如果为空树,则直接返回 return queue = [self.root] # 存储存在的元素,通过 cur_node 验证 while queue: # pop 方法直到为 [] 为止 cur_node = queue.pop(0) # 取出第一个元素 print(cur_node.data) # 输出结点 if cur_node.lchild is not None: # 如果存在左结点 queue.append(cur_node.lchild) # 添加到列表后 if cur_node.rchild is not None: # 如果存在右结点 queue.append(cur_node.rchild) # 添加到列表后
深度遍历 class Node(object): '''定义一个结点,有左孩子和右孩子''' def __init__(self,data): # 结点数据 self.data = data # 左、右 孩子指向为空 self.lchild = None self.rchild = None class BinaryTree(object): '''二叉树''' def __init__(self): # 根结点默认为空 self.root = None def add(self,data): # 添加数据到二叉树中 向最后进行添加数据 # 处理顺序:父结点 左孩子 右孩子 node = Node(data) # 如果为空树 if self.root is None: self.root = node # 空树,加入数据则放在根节点处 return queue = [self.root] # 添加根节点,作为存在该结点的标志 while queue: # 如果 queue 不为空 cur_node = queue.pop(0) # 当前结点指向根节点,取第一个元素 if cur_node.lchild is None : # 如果左结点为空 cur_node.lchild = node return else: # 添加到指针内,证明存在左结点 queue.append(cur_node.lchild) if cur_node.rchild is None: # 如果右结点为空 cur_node.rchild = node return else: # 添加到指针内,证明存在右结点 queue.append(cur_node.rchild) def pre_order(self,node): '''先序遍历 -> 根左右''' if node is None: return print(node.data,end = " ") self.pre_order(node,lchild) # 一直递归左面结点,返回后遍历右面 self.pre_order(node,rchild) # 开始遍历右侧,直到为空 def in_order(self,node): '''中序遍历 -> 左根右''' if node is None: return self.in_order(node,lchild) # 一直递归左面结点 print(node.data,end = " ") # 打印输出数据 self.in_order(node,rchild) # 遍历右侧数据 def post_order(self,node): '''后序遍历 -> 左右根''' if node is None: return self.post_order(node,lchild) # 一直递归左面结点 self.post_order(node,rchild) # 一直递归右面结点 print(node.data,end = " ")
单链表
''' is_empty() 链表是否为空 length() 查询链表长度 travel() 遍历整个链表 add(item) 链表头部添加元素 append(item) 链表尾部添加元素 insert(pos,item) 指定位置添加元素 remove(item) 删除节点 search(item) 查找节点是否存在 ''' class SingleNode(object): '''单链表的节点''' def __init__(self,item): self.item = item # 数据域 self.next = None # 指针域next指向下一个节点 def is_empty(self): '''判断链表是否为空,看头结点是否为空''' return self._head == None def length(self): '''链表长度,遍历链表,每遍历一次就进行加一操作''' cur = self._head #令cur当前指向头节点位置 count = 0 #count用来返回单链表长度 while cur != None: count = count + 1 cur = cur.next #到达下一个指针域 return count def travel(self): '''遍历单链表,对遍历到的单链表元素取出数据域输出''' cur = self._head#指向头结点 while cur != None: print(cur.item)#输出当前节点的元素 cur = cur.next#指向下一个节点 print(" ") def add(self,item): '''在单链表头部添加数据域为item元素的节点, 使包含有item元素的节点的下一个节点为头结点(没进行添加之前的)''' node = SingleNode(item) # 创建连接,使头结点为第二个节点 node.next = self._head # 对头结点进行重新命名 self._head = node def append(self,item): '''尾部添加元素,当单链表为空时,直接添加。 当单链表不为空时,在尾部添加(进行遍历操作,直到最后一个节点)''' # 创建节点元素存放item元素 node = SingleNode(item) if self.is_empty():#如果链表为空 self._head = node else: cur = self._head #令指针指向头结点 while cur.next != None:#进行遍历 cur = cur.next#依次向下进行遍历,直到最后一个节点 cur.next = node#让最后一个节点为node,包含有item的元素的节点 def insert(self,pos,item): '''在指定pos位置,添加包含有item元素的节点''' if pos <= 0: #当pos为小于等于0的位置时,将item添加在头部 self.add(item) elif pos >= self.length(): # 当pos大于等于链表长度时,将item添加在尾部 self.append(item) else:#既不在头部,又不在尾部 '''创建pre指针,指向pos的前一个位置''' node = SingleNode(item) # 存储item元素的节点 count = 0 # pre用来指向位置pos的前一个位置pos-1,从头结点开始 pre = self._head while count < pos - 1: # 当count为pos-1时,pre为要插入位置的前一个节点 count += 1 pre = pre.next node.next = pre.next #先连接原来链表中pos位置后面节点左面的线 pre.next = node#连接原来链表中前一个节点的右面的线 def remove(self,item): cur = self._head pre = None while cur != None: # 当单链表不为空时 if cur.item == item: # 如果cur所指向的节点的元素item与要删除的item元素一致 if not pre: # pre 如果还是None 说明是头结点 # pre = None # print(not pre) # True self._head = cur.next#当前cur指向第一个节点 # cur.next为原链表的第二个节点 else: #cur为要删除的节点,但不是头结点 '''pre为cur的前一个节点,cur为要删除的节点 使用cur节点的后一个节点的左连线连接删除节点的前一个元素的右连线''' pre.next = cur.next else:#当cur指向的节点所包含的item元素不是要寻找的item时 pre = cur cur = cur.next #继续向下寻找 def search(self,item): '''查看链表中是否存在item元素,通过遍历进行查找''' cur = self._head #指向头结点 while cur != None:#当cur指向的不为空时 if cur.item == item:#当找到该元素时 return True cur = cur.next#在while循环内部,不断进行遍历 return False
单向循环链表
''' is_empty() 链表是否为空 length() 查询链表长度 travel() 遍历整个链表,到头节点结束 add(item) 链表头部添加元素(头节点作为下一个节点,最后一个节点为node节点) append(item) 链表尾部添加元素,头节点为node的下一个节点 insert(pos,item) 指定位置添加元素 remove(item) 删除节点 search(item) 查找节点是否存在 ''' class Node(object): """节点""" def __init__(self, item): self.item = item self.next = None class SinCycLinkedlist(object): """单向循环链表""" def __init__(self): self._head = None def is_empty(self): """判断链表是否为空""" return self._head == None def length(self): """返回链表的长度""" # 如果链表为空,返回长度0 if self.is_empty(): return 0 count = 1 cur = self._head while cur.next != self._head: count += 1 cur = cur.next return count def travel(self): """遍历链表""" if self.is_empty(): return cur = self._head print (cur.item,) while cur.next != self._head: cur = cur.next print(cur.item,) print ("") def add(self, item): """头部添加节点""" node = Node(item) if self.is_empty(): self._head = node node.next = self._head else: #添加的节点指向_head node.next = self._head # 移到链表尾部,将尾部节点的next指向node cur = self._head while cur.next != self._head: cur = cur.next cur.next = node #_head指向添加node的 self._head = node def append(self, item): """尾部添加节点""" node = Node(item) if self.is_empty(): self._head = node node.next = self._head else: # 移到链表尾部 cur = self._head while cur.next != self._head: cur = cur.next # 将尾节点指向node cur.next = node # 将node指向头节点_head node.next = self._head def insert(self, pos, item): """在指定位置添加节点""" if pos <= 0: self.add(item) elif pos > (self.length()-1): self.append(item) else: node = Node(item) cur = self._head count = 0 # 移动到指定位置的前一个位置 while count < (pos-1): count += 1 cur = cur.next node.next = cur.next cur.next = node def remove(self, item): """删除一个节点""" # 若链表为空,则直接返回 if self.is_empty(): return # 将cur指向头节点 cur = self._head pre = None # 若头节点的元素就是要查找的元素item if cur.item == item: # 如果链表不止一个节点 if cur.next != self._head: # 先找到尾节点,将尾节点的next指向第二个节点 while cur.next != self._head: cur = cur.next # cur指向了尾节点 cur.next = self._head.next self._head = self._head.next else: # 链表只有一个节点 self._head = None else: pre = self._head # 第一个节点不是要删除的 while cur.next != self._head: # 找到了要删除的元素 if cur.item == item: # 删除 pre.next = cur.next return else: pre = cur cur = cur.next # cur 指向尾节点 if cur.item == item: # 尾部删除 pre.next = cur.next def search(self, item): """查找节点是否存在""" if self.is_empty(): return False cur = self._head if cur.item == item: return True while cur.next != self._head: cur = cur.next if cur.item == item: return True return False
双向链表
''' is_empty() 链表是否为空 length() 查询链表长度 travel() 遍历整个链表 add(item) 链表头部添加元素 append(item) 链表尾部添加元素 insert(pos,item) 指定位置添加元素 remove(item) 删除节点 search(item) 查找节点是否存在 ''' class Node(object): """双向链表节点""" def __init__(self, item): self.item = item self.next = None self.pre = None class DLinkList(object): """双向链表""" def __init__(self): self._head = None def is_empty(self): """判断链表是否为空""" return self._head == None def length(self): """返回链表的长度""" cur = self._head count = 0 while cur != None: count += 1 cur = cur.next return count def travel(self): """遍历链表""" cur = self._head while cur != None: print(cur.item,) cur = cur.next print(" ") def add(self, item): """头部插入元素""" node = Node(item) if self.is_empty(): # 如果是空链表,将_head指向node self._head = node else: # 将node的next指向_head的头节点 node.next = self._head # 将_head的头节点的pre指向node self._head.pre = node # 将_head 指向node self._head = node def append(self, item): """尾部插入元素""" node = Node(item) if self.is_empty(): # 如果是空链表,将_head指向node self._head = node else: # 移动到链表尾部 cur = self._head while cur.next != None: cur = cur.next # 将尾节点cur的next指向node(先左后右) cur.next = node # 将node的pre指向cur node.pre = cur def search(self, item): """查找元素是否存在""" cur = self._head while cur != None: if cur.item == item: return True cur = cur.next return False def insert(self, pos, item): """在指定位置添加节点""" if pos <= 0: self.add(item) elif pos > (self.length()-1): self.append(item) else: node = Node(item) cur = self._head count = 0 # 移动到指定位置的前一个位置 while count < (pos-1): count += 1 cur = cur.next # 将node的pre指向cur(node左右,cur右左) node.pre = cur # 将node的next指向cur的下一个节点 node.next = cur.next # 将cur的下一个节点的pre指向node cur.next.pre = node # 将cur的next指向node cur.next = node def remove(self, item): """删除元素""" if self.is_empty(): return else: cur = self._head if cur.item == item: # 如果首节点的元素即是要删除的元素 if cur.next == None: # 如果链表只有这一个节点 self._head = None else: # 将第二个节点的pre设置为None cur.next.pre = None # 将_head指向第二个节点 self._head = cur.next return while cur != None: if cur.item == item: # 将cur的前一个节点的next指向cur的后一个节点 cur.pre.next = cur.next # 将cur的后一个节点的pre指向cur的前一个节点 cur.next.pre = cur.pre break cur = cur.next
队列
''' Queue() 创建一个空队列 enqueue(item) 添加元素 dequeue() 从队列头部删除一个元素 is_empty() 判断一个队列是否为空 size() 返回队列的大小 ''' class Queue(object): '''队列''' def __init__(self): self.items = [] def is_empty(self): return self.items == [] def enqueue(self,item): '''进队列''' self.items.insert(0,item) def dequeue(self): '''出队列''' return self.items.pop() def size(self): '''返回队列的大小''' return len(self.items)
双端队列
''' Deque() 创建一个空的双端队列 add_front(item) 从队头加入一个item元素 add_rear(item) 从队尾加入一个item元素 remove_front() 从队头删除一个item元素 remove_rear() 从队尾删除一个item元素 is_empty() 判断双端队列是否为空 size() 返回队列的大小 ''' class Deque(object): '''双端队列''' def __init__(self): self.items = [] def is_empty(self): """判断队列是否为空""" return self.items == [] def add_front(self,item): """在队头添加元素""" self.items.insert(0,item) def add_rear(self,item): """在队尾添加元素""" self.items.append(item) def remove_front(self): """从队头删除元素""" return self.items.pop(0) def remove_rear(self): """从队尾删除元素""" return self.items.pop() def size(self): """返回队列大小""" return len(self.items)
栈
''' Stack() 创建一个新的空栈 push(item) 添加一个新的元素item到栈顶 pop() 弹出栈顶元素 peek() 返回栈顶元素 is_empty() 判断栈是否为空 size() 返回栈的元素个数 ''' class Stack(object): '''栈''' def __init__(self): self.items = [] def is_empty(self): """判断是否为空""" return self.items == [] def push(self,item): """加入元素""" self.items.append(item) def pop(self): """弹出元素""" return self.items.pop() def peek(self): """返回栈顶元素""" return self.items[len(self.items)-1] def size(self): return len(self.items)
创建二叉树
class Node(object): """节点类""" def __init__(self, elem=-1, lchild=None, rchild=None): self.elem = elem self.lchild = lchild self.rchild = rchild class Tree(object): """树类""" def __init__(self, root=None): self.root = root def add(self, elem): """为树添加节点""" node = Node(elem) #如果树是空的,则对根节点赋值 if self.root == None: self.root = node else: queue = [] queue.append(self.root) #对已有的节点进行层次遍历 while queue: #弹出队列的第一个元素 cur = queue.pop(0) if cur.lchild == None: cur.lchild = node return elif cur.rchild == None: cur.rchild = node return else: #如果左右子树都不为空,加入队列继续判断 queue.append(cur.lchild) queue.append(cur.rchild)
二叉树的层次遍历
def breadth_travel(self, root): """利用队列实现树的层次遍历""" if root == None: return queue = [] queue.append(root) while queue: node = queue.pop(0) print(node.elem,) if node.lchild != None: queue.append(node.lchild) if node.rchild != None: queue.append(node.rchild)
二叉树的深度遍历
def preorder(self, root): """递归实现先序遍历""" if root == None: return print(root.elem) self.preorder(root.lchild) self.preorder(root.rchild) def inorder(self, root): """递归实现中序遍历""" if root == None: return self.inorder(root.lchild) print(root.elem) self.inorder(root.rchild) def postorder(self, root): """递归实现后序遍历""" if root == None: return self.postorder(root.lchild) self.postorder(root.rchild) print(root.elem)
邻接矩阵
class Vertex: def __init__(self, node): self.id = node # Mark all nodes unvisited self.visited = False def addNeighbor(self, neighbor, G): G.addEdge(self.id, neighbor) def getConnections(self, G): return G.adjMatrix[self.id] def getVertexID(self): return self.id def setVertexID(self, id): self.id = id def setVisited(self): self.visited = True def __str__(self): return str(self.id) class Graph: def __init__(self, numVertices=10, directed=False): self.adjMatrix = [[None] * numVertices for _ in range(numVertices)] self.numVertices = numVertices self.vertices = [] self.directed = directed for i in range(0, numVertices): newVertex = Vertex(i) self.vertices.append(newVertex) def addVertex(self, vtx, id): #增加点,这个function没有扩展功能 if 0 <= vtx < self.numVertices: self.vertices[vtx].setVertexID(id) def getVertex(self, n): for vertxin in range(0, self.numVertices): if n == self.vertices[vertxin].getVertexID(): return vertxin return None def addEdge(self, frm, to, cost=0): #返回全部连线/航线 #print("from",frm, self.getVertex(frm)) #print("to",to, self.getVertex(to)) if self.getVertex(frm) is not None and self.getVertex(to) is not None: self.adjMatrix[self.getVertex(frm)][self.getVertex(to)] = cost if not self.directed: # For directed graph do not add this self.adjMatrix[self.getVertex(to)][self.getVertex(frm)] = cost def getVertices(self): vertices = [] for vertxin in range(0, self.numVertices): vertices.append(self.vertices[vertxin].getVertexID()) return vertices def printMatrix(self): for u in range(0, self.numVertices): row = [] for v in range(0, self.numVertices): row.append(str(self.adjMatrix[u][v]) if self.adjMatrix[u][v] is not None else '/') print(row) def getEdges(self): edges = [] for v in range(0, self.numVertices): for u in range(0, self.numVertices): if self.adjMatrix[u][v] is not None: vid = self.vertices[v].getVertexID() wid = self.vertices[u].getVertexID() edges.append((vid, wid, self.adjMatrix[u][v])) return edges def getNeighbors(self, n): neighbors = [] for vertxin in range(0, self.numVertices): if n == self.vertices[vertxin].getVertexID(): for neighbor in range(0, self.numVertices): if (self.adjMatrix[vertxin][neighbor] is not None): neighbors.append(self.vertices[neighbor].getVertexID()) return neighbors def isConnected(self, u, v): uidx = self.getVertex(u) vidx = self.getVertex(v) return self.adjMatrix[uidx][vidx] is not None def get2Hops(self, u): #转一次机可以到达哪里 neighbors = self.getNeighbors(u) print(neighbors) hopset = set() for v in neighbors: hops = self.getNeighbors(v) hopset |= set(hops) return list(hopset)
邻接表
import sys class Vertex: def __init__(self, node): self.id = node self.adjacent = {} #为所有节点设置距离无穷大 self.distance = sys.maxsize # 标记未访问的所有节点 self.visited = False # Predecessor self.previous = None def addNeighbor(self, neighbor, weight=0): self.adjacent[neighbor] = weight # returns a list def getConnections(self): # neighbor keys return self.adjacent.keys() def getVertexID(self): return self.id def getWeight(self, neighbor): return self.adjacent[neighbor] def setDistance(self, dist): self.distance = dist def getDistance(self): return self.distance def setPrevious(self, prev): self.previous = prev def setVisited(self): self.visited = True def __str__(self): return str(self.id) + ' adjacent: ' + str([x.id for x in self.adjacent]) def __lt__(self, other): return self.distance < other.distance and self.id < other.id class Graph: def __init__(self, directed=False): # key is string, vertex id # value is Vertex self.vertDictionary = {} self.numVertices = 0 self.directed = directed def __iter__(self): return iter(self.vertDictionary.values()) def isDirected(self): return self.directed def vectexCount(self): return self.numVertices def addVertex(self, node): self.numVertices = self.numVertices + 1 newVertex = Vertex(node) self.vertDictionary[node] = newVertex return newVertex def getVertex(self, n): if n in self.vertDictionary: return self.vertDictionary[n] else: return None def addEdge(self, frm, to, cost=0): if frm not in self.vertDictionary: self.addVertex(frm) if to not in self.vertDictionary: self.addVertex(to) self.vertDictionary[frm].addNeighbor(self.vertDictionary[to], cost) if not self.directed: # For directed graph do not add this self.vertDictionary[to].addNeighbor(self.vertDictionary[frm], cost) def getVertices(self): return self.vertDictionary.keys() def setPrevious(self, current): self.previous = current def getPrevious(self, current): return self.previous def getEdges(self): edges = [] for key, currentVert in self.vertDictionary.items(): for nbr in currentVert.getConnections(): currentVertID = currentVert.getVertexID() nbrID = nbr.getVertexID() edges.append((currentVertID, nbrID, currentVert.getWeight(nbr))) # tuple return edges def getNeighbors(self, v): vertex = self.vertDictionary[v] return vertex.getConnections()
实现优先级队列
import heapq class PriorityQueue: def __init__(self): self._queue=[] self._index=0 def push(self,item,priority): heapq.heappush(self._queue,(-priority,self._index,item)) self._index+=1 def pop(self): return heapq.heappop(self._queue)[-1] class Item: def __init__(self,name): self.name=name def __repr__(self): return 'Item({!r})'.format(self.name) q=PriorityQueue() q.push(Item('AAA'),1) q.push(Item('BBB'),4) q.push(Item('CCC'),5) q.push(Item('DDD'),1) print(q.pop()) print(q.pop()) print(q.pop())