冒泡算法,选择排序算法,插入排序算法,快速排序算法,归并排序算法,计数排序算法,链表算法(单例)
1.冒泡算法
# 冒泡算法 # 时间复杂度O(n^2),因为循环2次输出 # 空间复杂度:O(1),在循环中没有创作新的空间所以是O(1) li = [5, 3, 8, 1, 2, 4, 9, 7, 6] # 比较方式是第一位和第二位进行比较,如果第一位的数大于第二位数就进行交换,然后第二位和第三位进行比较.就这样依次进行比较 # 然后最右边的数就会变成最大的数 def bubble_sort(li): # 从第一个开始比大小,只要比长度-1次就可以,比如现在li的长度是9,比8次就可以比完 ,多比较一次没意义所以是len(li)-1 for i in range(len(li) - 1): # 这里设置flag参数是为了优化冒泡排序,如果下面的排序比较if li[j] > li[j + 1]: # 不通过的话说明给的列表里面的数字是已经排序好的所以就不用进行比较直接return返回这个列表 flag = False # 这里len(li) - 1的意思和上面一样,再减去i是因为全部比较完一次之后, # 最右侧的肯定是最大数,下一轮就不用比较最右侧的数,可以少比较一次 # 所以每次比较完一轮之后要减去 i ,最后结果是len(li) - 1 - i for j in range(len(li) - 1 - i): # 从左到右进行依次比较,如果左边的数大于右边的数就进行位置交换 if li[j] > li[j + 1]: # 右边的数和左边的数进行交换赋值 li[j], li[j + 1] = li[j + 1], li[j] flag = True # 直接返回该列表 if not flag: return bubble_sort(li) print(li)
2.选择排序算法
# 选择排序算法 # 时间复杂度: O(n^2) 空间复杂度: O(1) # 比较的方式是最左边(第一位)的数和第二位进行比较,如果第二位的数小于第一位的数就进行交换.然后最左边(第一位)的数,就变成比较之后小的呢位数 # 然后最左边(第一位)的数再和第三位进行比较,如果第三位数大就不进行交换,小的话就再进行交换 # 这样一轮比较下来最后最左边(第一位)的数就会变成列表最小的数 # 然后第二轮就用第二位的数进行比较,依次进行比较.最后就排序完成
li = [5, 3, 8, 1, 2, 4, 9, 7, 6]
def select_sort(li): # 从第一个开始比大小,只要比长度-1次就可以,比如现在li的长度是9,比8次就可以比完,多比较一次没意义所以是len(li)-1 for i in range(len(li) - 1): # 这个代表从索引0第一个开始比较 minLoc = i # 从索引第二位开始进行匹配,到总共的长度的次数.(相等与总长度的次数-1次) for j in range(i + 1, len(li)): # 索引0位和索引1位进行比较如果大于进行交换,到最后最小的在索引0位 # 然后下一轮再索引1位进行依次比较 if li[minLoc] > li[j]: # 比较成功后进行位置交换 li[minLoc], li[j] = li[j], li[minLoc] select_sort(li) print(li)
3.插入排序算法
# 插入排序算法 # 时间复杂度: O(n^2) 空间复杂度: O(1) # 比较方法是第一次是索引第二位(数字3也是tmp)和索引第一位(数字5)进行比较,如果索引的第一位比第二位大,第二位的值(数字3)会变成第一位(数字5). # 然后 j 索引-1(如果索引的值成为负数说明左边已经没有数需要进行比较.这样就会退出while循环 # 然后 j + 1就变成索引0,然后第一位的数再赋值成tmp(数字3).(就是比较下来小的数). # 接下来一轮索引2(数字8也是tmp),和(j=i-1)索引1(数字5)进行比较.索引2(数字8)比索引1(数字5)大while条件不成立,然后(j+1)索引2还是8(tmp),数字不变进行下一轮比较 # 再接下来索引3(数字1也是tmp)和索引2(数字8)进行比较,索引3(数字1)比索引2(数字8)小,索引3(数字1)变成数字8,然后索引1(数字5)的值和tmp(数字1)进行比较 # 结果索引1(数字5大)然后索引2(数字8)变成索引1(数字5). # 然后索引0(数字3)再和tmp(数字1)进行比较,结果索引0(数字3)数字大然后索引1(数字5)变成索引0(数字3) # 再然后 j 索引-1(如果索引的值成为负数说明左边已经没有数需要进行比较.这样就会退出while循环, # 然后 j + 1就变成索引0,然后第一位的数再赋值成tmp(数字1).(最后索引0就是最小的数这样开始排序).就这样依次进行对比 li = [5, 3, 8, 1, 2, 4, 9, 7, 6] def insert_sort(li): # 插入排序需要每一次和左边的数进行比较,所以索引范围是从1到范围长度 for i in range(1,len(li)): tmp = li[i] # 索引减一是为了和左边的数进行比较 j = i - 1 # 索引没有为-1说明还有值可以进行比较 并且 左边的值要大于 tmp while j >=0 and li[j] > tmp: # 条件成立当前的索引的值被左边的值覆盖 li[j+1] = li[j] # 然后再和再左边的索引值进行比较 j = j -1 # 到这里说明j = -1 没有值再需要进行比较索引0直接变成tmp(比较下来最小的值) li[j+1] = tmp insert_sort(li) print(li)
4.快速排序
# 快速排序 # 时间复杂度: O(nlogn) def partition(li,left,right): temp = li[left] while left < right: while left < right and li[right] >= temp: right = right - 1 li[left] = li[right] while left < right and li[left] <= temp: left = left + 1 li[right] = li[left] li[left] = temp return left def quick_sort(li,left,right): if left < right: mid = partition(li,left,right) quick_sort(li,left,mid-1) quick_sort(li,mid+1,right) li = [5, 3, 8, 1, 2, 4, 9, 7, 6] quick_sort(li, 0, len(li)-1) print(li)
5.归并排序
# 归并排序 # 时间复杂度: O(nlogn) # 空间复杂度: O(n) def merge(li, low, mid, high ): i = low j = mid + 1 ltmp = [] while i <= mid and j <= high: if li[i] < li[j]: ltmp.append(li[i]) i = i + 1 else: ltmp.append(li[j]) j = j + 1 while i <= mid: ltmp.append(li[i]) i = i + 1 while j <= high: ltmp.append(li[j]) j = j + 1 li[low:high+1] = ltmp def merge_sort(li, low, high): if low < high: mid = (low + high) // 2 merge_sort(li, low, mid) merge_sort(li, mid+1, high) print("归并前: ",li[low:high+1]) merge(li, low, mid, high) print("归并后: ",li[low:high + 1]) li = [10, 4, 6, 3, 8, 2, 5, 2, 1, 7, 0] # 索引范围0~10 merge_sort(li, 0, 10) print(li)
6.计数排序
计数排序 def countsort(li): count = [0 for i in range(11)] for i in li: # print(i) count[i] += 1 li.clear() for n, num in enumerate(count): print(n, num) for i in range(num): li.append(n) li = [10,4,6,3,8,2,5,2,1,7,0] countsort(li) print(li)
7.链表算法(单例)
# 链表算法(单例) class Hero(object): def __init__(self, no=None, name=None, nickname=None, Next=None): self.no = no self.name = name self.nickname = nickname self.Next = Next def addHero(head, hero): cur = head # 第一种 添加到链表后面 # while cur.Next != None: # cur = cur.Next # cur.Next = hero ###第二种 指定添加 # print(cur.Next,"1") while cur.Next != None: ### 找到了指定的位置, 直接跳出while循环 if cur.Next.no > hero.no : break ### 没有找到的话, 继续找 cur = cur.Next hero.Next = cur.Next cur.Next = hero def getAll(head): cur = head while cur.Next != None: cur = cur.Next print('编号是:%s, 姓名是:%s, 外号是%s' % (cur.no, cur.name, cur.nickname) ) head = Hero() hero1 = Hero(1, '宋江', '及时雨') # print(hero1) addHero(head, hero1) hero2 = Hero(2, '卢俊义', '玉麒麟') addHero(head, hero2) hero4 = Hero(4, '武松', '打老虎') addHero(head, hero4) hero3 = Hero(3, '金莲', '武大郎') addHero(head, hero3) getAll(head)