初始数据结构(python语言)
数据结构
概念:数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成
算法复杂度
时间复杂度
计算方法
空间复杂度
空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度,记做S(n)=O(f(n))。比如直接插入排序的时间复杂度是O(n^2),空间复杂度是O(1) 。而一般的递归算法就要有O(n)的空间复杂度了,因为每次递归都要存储返回信息。一个算法的优劣主要从算法的执行时间和所需要占用的存储空间两个方面衡量
对于一个算法,其 时间复杂度和空间复杂度往往是相互影响的。当追求一个较好的时间复杂度时,可能会使空间复杂度的性能变差,即可能导致占用较多的存储空间;反之,当追求一个较好的空间复杂度时,可能会使时间复杂度的性能变差,即可能导致占用较长的运行时间。另外,算法的所有性能之间都存在着或多或少的相互影响。因此,当设计一个算法(特别是大型算法)时,要综合考虑算法的各项性能,算法的使用频率,算法处理的数据量的大小,算法描述语言的特性,算法运行的机器系统环境等各方面因素,才能够设计出比较好的算法。算法的时间复杂度和空间复杂度合称为算法的复杂度
线性表
顺序表
顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中
链表
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间。
而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)
相关术语:
前驱指针:指向上一个节点
后继指针:指向下一节点
单向链表: 一个节点,只包含一个指针,就是后继指针,用来指向下一节点。尾节点指向None
双向链表:一个节点,包含两个指针,前驱、后继指针。注意点 修改一个节点的时候,要记住前后节点的位置
单向循环:一个节点,只包含一个指针,用来指向下一节点,尾节点的下一节点就是头节点
- # coding:utf-8
- class Node(object):
- """节点"""
- def __init__(self, elem):
- self.elem = elem
- self.next = None
- class SingleLinkList(object):
- """单链表"""
- def __init__(self, node=None):
- self.__head = node
- def is_empty(self):
- """链表是否为空"""
- return self.__head == None
- def length(self):
- """链表长度"""
- # cur游标,用来移动遍历节点
- cur = self.__head
- # count记录数量
- count = 0
- while cur != None:
- count += 1
- cur = cur.next
- return count
- def travel(self):
- """遍历整个链表"""
- cur = self.__head
- while cur != None:
- print(cur.elem, end=" ")
- cur = cur.next
- print("")
- 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 != None:
- cur = cur.next
- cur.next = node
- def insert(self, pos, item):
- """指定位置添加元素
- :param pos 从0开始
- """
- if pos <= 0:
- self.add(item)
- elif pos > (self.length() - 1):
- self.append(item)
- else:
- pre = self.__head
- count = 0
- while count < (pos - 1):
- count += 1
- pre = pre.next
- # 当循环退出后,pre指向pos-1位置
- node = Node(item)
- node.next = pre.next
- pre.next = node
- def remove(self, item):
- """删除节点"""
- cur = self.__head
- pre = None
- while cur != 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):
- """查找节点是否存在"""
- cur = self.__head
- while cur != None:
- if cur.elem == item:
- return True
- else:
- cur = cur.next
- return False
- if __name__ == "__main__":
- ll = SingleLinkList()
- print(ll.is_empty())
- print(ll.length())
- ll.append(1)
- print(ll.is_empty())
- print(ll.length())
- ll.append(2)
- ll.add(8)
- ll.append(3)
- ll.append(4)
- ll.append(5)
- ll.append(6)
- # 8 1 2 3 4 5 6
- ll.insert(-1, 9) # 9 8 1 23456
- ll.travel()
- ll.insert(3, 100) # 9 8 1 100 2 3456
- ll.travel()
- ll.insert(10, 200) # 9 8 1 100 23456 200
- ll.travel()
- ll.remove(100)
- ll.travel()
- ll.remove(9)
- ll.travel()
- ll.remove(200)
- ll.travel()
- """
- True
- 0
- False
- 1
- 9 8 1 2 3 4 5 6
- 9 8 1 100 2 3 4 5 6
- 9 8 1 100 2 3 4 5 6 200
- 9 8 1 2 3 4 5 6 200
- 8 1 2 3 4 5 6 200
- 8 1 2 3 4 5 6
- """
单向链表
- # coding:utf-8
- class Node(object):
- """结点"""
- def __init__(self, item):
- self.elem = item
- self.next = None
- self.prev = None
- class DoubleLinkList(object):
- """双链表"""
- def __init__(self, node=None):
- self.__head = node
- def is_empty(self):
- """链表是否为空"""
- return self.__head == None
- def length(self):
- """链表长度"""
- # cur游标,用来移动遍历节点
- cur = self.__head
- # count记录数量
- count = 0
- while cur != None:
- count += 1
- cur = cur.next
- return count
- def travel(self):
- """遍历整个链表"""
- cur = self.__head
- while cur != None:
- print(cur.elem, end=" ")
- cur = cur.next
- print("")
- def add(self, item):
- """链表头部添加元素,头插法"""
- node = Node(item)
- node.next = self.__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 != None:
- cur = cur.next
- cur.next = node
- node.prev = cur
- def insert(self, pos, item):
- """指定位置添加元素
- :param pos 从0开始
- """
- if pos <= 0:
- self.add(item)
- elif pos > (self.length()-1):
- self.append(item)
- else:
- cur = self.__head
- count = 0
- while count < pos:
- count += 1
- cur = cur.next
- # 当循环退出后,cur指向pos位置
- node = Node(item)
- node.next = cur
- node.prev = cur.prev
- cur.prev.next = node
- cur.prev = node
- def remove(self, item):
- """删除节点"""
- cur = self.__head
- while cur != 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):
- """查找节点是否存在"""
- cur = self.__head
- while cur != None:
- if cur.elem == item:
- return True
- else:
- cur = cur.next
- return False
- if __name__ == "__main__":
- ll = DoubleLinkList()
- print(ll.is_empty())
- print(ll.length())
- ll.append(1)
- print(ll.is_empty())
- print(ll.length())
- ll.append(2)
- ll.add(8)
- ll.append(3)
- ll.append(4)
- ll.append(5)
- ll.append(6)
- # 8 1 2 3 4 5 6
- ll.insert(-1, 9) # 9 8 1 23456
- ll.travel()
- ll.insert(3, 100) # 9 8 1 100 2 3456
- ll.travel()
- ll.insert(10, 200) # 9 8 1 100 23456 200
- ll.travel()
- ll.remove(100)
- ll.travel()
- ll.remove(9)
- ll.travel()
- ll.remove(200)
- ll.travel()
- """
- True
- 0
- False
- 1
- 9 8 1 2 3 4 5 6
- 9 8 1 100 2 3 4 5 6
- 9 8 1 100 2 3 4 5 6 200
- 9 8 1 2 3 4 5 6 200
- 8 1 2 3 4 5 6 200
- 8 1 2 3 4 5 6
- """
双向链表
- # coding:utf-8
- class Node(object):
- """节点"""
- def __init__(self, elem):
- self.elem = elem
- self.next = None
- class SingleCycleLinkList(object):
- """单向循环链表"""
- def __init__(self, node=None):
- self.__head = node
- if node:
- node.next = node
- def is_empty(self):
- """链表是否为空"""
- return self.__head == None
- def length(self):
- """链表长度"""
- if self.is_empty():
- return 0
- # cur游标,用来移动遍历节点
- cur = self.__head
- # count记录数量
- count = 1
- 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.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
- # cur.next = node
- cur.next = self.__head
- 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
- # node.next = cur.next
- node.next = self.__head
- cur.next = node
- def insert(self, pos, item):
- """指定位置添加元素
- :param pos 从0开始
- """
- if pos <= 0:
- self.add(item)
- elif pos > (self.length()-1):
- self.append(item)
- else:
- pre = self.__head
- count = 0
- while count < (pos-1):
- count += 1
- pre = pre.next
- # 当循环退出后,pre指向pos-1位置
- 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
- pre.next = self.__head
- def search(self, item):
- """查找节点是否存在"""
- if self.is_empty():
- return False
- cur = self.__head
- while cur.next != self.__head:
- if cur.elem == item:
- return True
- else:
- cur = cur.next
- # 退出循环,cur指向尾节点
- if cur.elem == item:
- return True
- return False
- if __name__ == "__main__":
- ll = SingleCycleLinkList()
- print(ll.is_empty())
- print(ll.length())
- ll.append(1)
- print(ll.is_empty())
- print(ll.length())
- ll.append(2)
- ll.add(8)
- ll.append(3)
- ll.append(4)
- ll.append(5)
- ll.append(6)
- # 8 1 2 3 4 5 6
- ll.insert(-1, 9) # 9 8 1 23456
- ll.travel()
- ll.insert(3, 100) # 9 8 1 100 2 3456
- ll.travel()
- ll.insert(10, 200) # 9 8 1 100 23456 200
- ll.travel()
- ll.remove(100)
- ll.travel()
- ll.remove(9)
- ll.travel()
- ll.remove(200)
- ll.travel()
- """
- True
- 0
- False
- 1
- 9 8 1 2 3 4 5 6
- 9 8 1 100 2 3 4 5 6
- 9 8 1 100 2 3 4 5 6 200
- 9 8 1 2 3 4 5 6 200
- 8 1 2 3 4 5 6 200
- 8 1 2 3 4 5 6
- """
单向循环链表
排序
排序算法的稳定&不稳定性
假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
冒泡排序
概念:冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
- 代码理解:就是借用两个for 循环(内循环 外循环)
- # coding:utf-8
- def bubble_sort(alist):
- """冒泡排序"""
- n = len(alist)
- for j in range(n-1):
- for i in range(0, n-1-j):
- # 从头走到尾
- if alist[i] > alist[i+1]:
- alist[i],alist[i+1] = alist[i+1], alist[i]
- if __name__ == "__main__":
- li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
- print(li)
- bubble_sort(li)
- print(li)
冒泡排序
选择排序
选择排序也是一种简单直观的排序算法。它的工作原理很容易理解:初始时在序列中找到最小(大)元素,放到序列的起始位置作为已排序序列;然后,再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
注意选择排序与冒泡排序的区别:冒泡排序通过依次交换相邻两个顺序不合法的元素位置,从而将当前最小(大)元素放到合适的位置;而选择排序每遍历一次都记住了当前最小(大)元素的位置,最后仅需一次交换操作即可将其放到合适的位置。
- def select_sort(alist):
- """选择排序"""
- 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[min_index] > alist[i]:
- min_index = i
- alist[j], alist[min_index] = alist[min_index], alist[j]
- if __name__ == "__main__":
- li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
- print(li)
- select_sort(li)
- print(li)
选择排序
插入排序
插入排序算法有种递归的思想在里面,它由N-1趟排序组成。初始时,只考虑序列下标0处的元素,只有一个元素,显然是有序的。
然后第一趟 对下标 1 处的元素进行排序,保证序列[0,1]上的元素有序;
第二趟 对下标 2 处的元素进行排序,保证序列[0,2]上的元素有序;
.....
.....
第N-1趟对下标 N-1 处的元素进行排序,保证序列[0,N-1]上的元素有序,也就是整个数组有序了。
它的递归思想就体现在:当对位置 i 处的元素进行排序时,[0,i-1]上的元素一定是已经有序的了。
- # coding:utf-8
- def insert_sort(alist):
- """插入排序"""
- n = len(alist)
- # 从右边的无序序列中取出多少个元素执行这样的过程
- for j in range(1, n):
- # j = [1, 2, 3, n-1]
- # i 代表内层循环起始值
- i = j
- # 执行从右边的无序序列中取出第一个元素,即i位置的元素,然后将其插入到前面的正确位置中
- while i > 0:
- if alist[i] < alist[i-1]:
- alist[i], alist[i-1] = alist[i-1], alist[i]
- i -= 1
- else:
- break
- if __name__ == "__main__":
- li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
- print(li)
- insert_sort(li)
- print(li)
插入排序
希尔排序
思想:将待排序列划分为若干组,在每一组内进行插入排序,以使整个序列基本有序,然后再对整个序列进行插入排序。



- # coding:utf-8
- def shell_sort(alist):
- """希尔排序"""
- # n=9
- n = len(alist)
- # gap =4
- gap = n // 2 # // 整除取整数
- # gap变化到0之前,插入算法执行的次数
- while gap > 0:
- # 插入算法,与普通的插入算法的区别就是gap步长
- for j in range(gap, n):
- # j = [gap, gap+1, gap+2, gap+3, ..., n-1]
- 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
- print('while:',alist)
- # 缩短gap步长
- print('for:',alist)
- gap //= 2
- if __name__ == "__main__":
- li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
- print(li)
- shell_sort(li)
- print(li)
- """
- [54, 26, 93, 17, 77, 31, 44, 55, 20]
- while: [54, 26, 93, 17, 77, 31, 44, 55, 20]
- while: [54, 26, 93, 17, 77, 31, 44, 55, 20]
- while: [54, 26, 55, 17, 77, 31, 93, 44, 20]
- while: [54, 26, 55, 17, 77, 31, 93, 44, 20]
- while: [20, 26, 55, 17, 54, 31, 93, 44, 77]
- for: [20, 26, 55, 17, 54, 31, 93, 44, 77]
- while: [20, 26, 55, 17, 54, 31, 93, 44, 77]
- while: [20, 77, 55, 26, 54, 31, 93, 44, 17]
- while: [20, 77, 54, 26, 55, 31, 93, 44, 17]
- while: [20, 77, 54, 26, 55, 31, 93, 44, 17]
- while: [20, 77, 54, 26, 55, 31, 93, 44, 17]
- while: [20, 77, 54, 26, 55, 31, 93, 44, 17]
- while: [17, 77, 20, 26, 54, 31, 55, 44, 93]
- for: [17, 77, 20, 26, 54, 31, 55, 44, 93]
- while: [17, 77, 20, 26, 54, 31, 55, 44, 93]
- while: [17, 20, 77, 26, 54, 31, 55, 44, 93]
- while: [17, 20, 26, 77, 54, 31, 55, 44, 93]
- while: [17, 20, 26, 54, 77, 31, 55, 44, 93]
- while: [17, 20, 26, 31, 54, 77, 55, 44, 93]
- while: [17, 20, 26, 31, 54, 55, 77, 44, 93]
- while: [17, 20, 26, 31, 44, 54, 55, 77, 93]
- while: [17, 20, 26, 31, 44, 54, 55, 77, 93]
- for: [17, 20, 26, 31, 44, 54, 55, 77, 93]
- [17, 20, 26, 31, 44, 54, 55, 77, 93]
- """
希尔排序
快速排序
- # coding:utf-8
- def quick_sort(alist, first, last):
- """快速排序"""
- if first >= last:
- return
- mid_value = alist[first]
- low = first
- high = last
- while low < high:
- # 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)
- if __name__ == "__main__":
- li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
- print(li)
- quick_sort(li, 0, len(li)-1)
- print(li)
快速排序
归并排序
概念:归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并
- # coding:utf-8
- 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(left, right)
- left_pointer, right_pointer = 0, 0
- result = []
- while left_pointer < len(left_li) and right_pointer < len(right_li):
- if left_li[left_pointer] <= right_li[right_pointer]:
- result.append(left_li[left_pointer])
- left_pointer += 1
- else:
- result.append(right_li[right_pointer])
- right_pointer += 1
- result += left_li[left_pointer:]
- result += right_li[right_pointer:]
- return result
- if __name__ == "__main__":
- li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
- print(li)
- sorted_li = merge_sort(li)
- print(li)
- print(sorted_li)
- """
- [54, 26, 93, 17, 77, 31, 44, 55, 20]
- [54, 26, 93, 17, 77, 31, 44, 55, 20]
- [17, 20, 26, 31, 44, 54, 55, 77, 93]
- """
归并排序
搜索
二分查找
说明:元素必须是有序的,如果是无序的则要先进行排序操作。
基本思想:也称为是折半查找,属于有序查找算法。用给定值k先与中间结点的关键字比较,中间结点把线形表分成两个子表,若相等则查找成功;若不相等,再根据k与该中间结点关键字的比较结果确定下一步查找哪个子表,这样递归进行,直到查找到或查找结束发现表中没有这样的结点。
复杂度分析:最坏情况下,关键词比较次数为log2(n+1),且期望时间复杂度为O(log2n);
- def binary_search(alist, item):
- """二分查找,递归"""
- n = len(alist)
- if n > 0:
- mid = n//2
- if alist[mid] == item:
- return True
- elif item < alist[mid]:
- return binary_search(alist[:mid], item)
- else:
- return binary_search(alist[mid+1:], item)
- return False
- def binary_search_2(alist, item):
- """二分查找, 非递归"""
- n = len(alist)
- first = 0
- last = n-1
- while first <= last:
- mid = (first + last)//2
- if alist[mid] == item:
- return True
- elif item < alist[mid]:
- last = mid - 1
- else:
- first = mid + 1
- return False
- if __name__ == "__main__":
- li = [17, 20, 26, 31, 44, 54, 55, 77, 93]
- print(binary_search(li, 55))
- print(binary_search(li, 100))
- print(binary_search_2(li, 55))
- print(binary_search_2(li, 100))
- """
- True
- False
- True
- False
- """
二分查找法
二叉树
相关术语:
二叉树性质



完全二叉树
若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。
满二叉树
- # coding:utf-8
- class Node(object):
- """"""
- def __init__(self, item):
- self.elem = item
- self.lchild = None
- self.rchild = None
- class Tree(object):
- """二叉树"""
- def __init__(self):
- self.root = None
- def add(self, item):
- node = Node(item)
- if self.root is 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:
- 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):
- """广度遍历"""
- if self.root is None:
- return
- queue = [self.root]
- 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 = Tree()
- tree.add(0)
- tree.add(1)
- tree.add(2)
- tree.add(3)
- tree.add(4)
- tree.add(5)
- tree.add(6)
- tree.add(7)
- tree.add(8)
- tree.add(9)
- tree.breadth_travel()
- print(" ")
- tree.preorder(tree.root)
- print(" ")
- tree.inorder(tree.root)
- print(" ")
- tree.postorder(tree.root)
- print(" ")
- """
- 0 1 2 3 4 5 6 7 8 9
- 0 1 3 7 8 4 9 2 5 6
- 7 3 8 1 9 4 0 5 2 6
- 7 8 3 9 4 1 5 6 2 0
- """
二叉树
先序遍历: 根 左 右
中序遍历: 左 根 右
后序遍历: 左 右 根
三种顺序之中:如果知道中序跟其中一个 ,就可以写出第三个顺序来
初始数据结构(python语言)的更多相关文章
- 0.数据结构(python语言) 基本概念 算法的代价及度量!!!
先看思维导图: *思维导图有点简陋,本着循循渐进的思想,这小节的知识大多只做了解即可. *重点在于算法的代价及度量!!!查找资料务必弄清楚. 零.四个基本概念 问题:一个具体的需求 问题实例:针对问题 ...
- 数据结构(python语言)目录链接
第一章 准备工作 课时0:0.数据结构(python语言) 基本概念 算法的代价及度量!!!
- 用python语言讲解数据结构与算法
写在前面的话:关于数据结构与算法讲解的书籍很多,但是用python语言去实现的不是很多,最近有幸看到一本这样的书籍,由Brad Miller and David Ranum编写的<Problem ...
- Python语言数据结构和语言结构(2)
目录 1. Python预备基础 2. Python数据类型 3. Python条件语句 4. while循环和for循环 1. Python预备基础 1.1 变量的命名 变量命名规则主要有以下几 ...
- 五种编程语言解释数据结构与算法——顺序表3(JavaScript与Python语言实现)
7.JavaScript语言实现 7.1.用ES6语法编写顺序表类 //1.创建类 class MyList { //1. initList(&L):初始化表.构造一个空的线性表.放回值应该是 ...
- Python语言学习之C++调用python
C++调用python 在C/C++中嵌入Python,可以使用Python提供的强大功能,通过嵌入Python可以替代动态链接库形式的接口,这样可以方便地根据需要修改脚本代码,而不用重新编译链接二进 ...
- 使用Python语言理解递归
递归 一个函数在执行过程中一次或多次调用其本身便是递归,就像是俄罗斯套娃一样,一个娃娃里包含另一个娃娃. 递归其实是程序设计语言学习过程中很快就会接触到的东西,但有关递归的理解可能还会有一些遗漏,下面 ...
- 强者联盟——Python语言结合Spark框架
引言:Spark由AMPLab实验室开发,其本质是基于内存的高速迭代框架,"迭代"是机器学习最大的特点,因此很适合做机器学习. 得益于在数据科学中强大的表现,Python语言的粉丝 ...
- Python语言程序设计之三--列表List常见操作和错误总结
最近在学习列表,在这里卡住了很久,主要是课后习题太多,而且难度也不小.像我看的这本<Python语言程序设计>--梁勇著,列表和多维列表两章课后习题就有93道之多.我的天!但是题目出的非常 ...
随机推荐
- 从锅炉工到AI专家(3)
剖析第一个例子 学习<机器学习>,很多IT高手是直接去翻看TensorFlow文档,但碰壁的很多.究其原因,TensorFlow的文档跨度太大了,它首先假设你已经对"机器学习&q ...
- 一个JavaWeb搭建的开源Blog系统,整合SSM框架
搬砖有暇,捣鼓了一个简单的Blog系统(项目地址https://github.com/lenve/JavaEETest/tree/master/MyBlog),适合以下人群学习: 1.已经掌握了jsp ...
- 记一次Eureka启动报Failed to start bean 'eurekaAutoServiceRegistration' 。。。错误
在一次项目迁移的过程中,新导入了两个依赖,结果项目启动就报错,如下: 主要原因是:Failed to start bean 'eurekaAutoServiceRegistration'; neste ...
- putty 默认颜色样式修改 for windows
一.导出 putty 注册表默认配置文件 1.1 打开注册表:运行 --» regedit 找到 putty 注册表文件: [HKEY_CURRENT_USER\Software\SimonTatha ...
- Linux基础知识第一讲,基本目录结构与基本命令
目录 一丶Window 与 Linux的目录结构 1.Windows 与 Linux目录简介 2.Linux目录主要作用 3.任务栏与菜单栏,与关闭按钮 二丶Linux终端与常见命令学习 1.终端中的 ...
- Oracle 连接 另一个Oracle数据库 服务器连接
一.场景 两台不同的服务器A.B分别装有不同业务的oracle数据库,因业务需要,现需要将B中test表的数据,定时同步到A中. 二.实现 根据以上场景,我想到了oracle中的dblink, ...
- C# 操作Excel图形——绘制、读取、隐藏、删除图形
简介 本篇文章将介绍C# 如何处理Excel图形相关的问题,包括以下内容要点: 1.绘制图形 1.1 绘制图形并添加文本到图形 1.2 添加图片到图形 1.3 设置图形阴影效果 1.4 设置图形透明度 ...
- SpringMVC页面向Controller传参
关于SpringMVC页面向Controller传参的问题,看了网上不少帖子,大多总结为以下几类: 1.直接把页面表单中相关元素的name属性对应的值作为Controller方法中的形参. 这个应该是 ...
- 原生JS实现简易轮播图
原生JS实现简易轮播图(渐变?) 最近做网页总是会用到轮播图,我就把之前写的轮播图单独拿出来吧,如果有...如果真的有人也需要也可以复制去用用啊..哈~.. window.onload = funct ...
- Adaptive Placeholders
https://wisdmlabs.com/blog/create-adaptive-placeholders-using-css/ https://circleci.com/blog/adaptiv ...