刚接触编程的同学可以看看的几个编程练习(python实现)(五)
本大白最近带一只小白入手编程,想法是在练习中学习,所以弄了几个题目。其中不少是经典的练习题,在很多编程入门书籍中都有出现;有的题涉及到一点数据结构的理念。在这里分享出来,刚接触编程的同学可以和我们一起做一做(无论学的是哪种语言都可以看一看,思路是通用的。这里我们学的是python),也欢迎大家指正。
24. 排序
1. 选择排序
设数据列表长度为n, 第一轮将0位置的数据不断与1至n-1位置的数据进行比较,这个过程中不断将较小的数放于0位置,这样经第一轮比较后最小的数放在了0位置; 第二轮类似地将1位置的数据不断与2至n-1位置的数据进行比较,这样第二小的数放在了1位置;依此进行n-1轮,完成排序。
[code]def choose_sort(number_list): n = len(number_list) for i in range(n-1): for j in range(i+1, n): if number_list[j] < number_list[i]: temp = number_list[i] number_list[i] = number_list[j] number_list[j] = temp x = [20, 20, 2, 3, 2, 5, 6, 1, -2, 3, 14, 12, 3, -1, -1] choose_sort(x) print(x)
选择排序也可以用递归的方法完成
[code]def choose_sort_recursive(number_list, low=0, high=0): high = len(number_list) - 1 if low < high: index_of_min = low min = number_list[low] for i in range(low+1, high+1): if number_list[i] < min: index_of_min = i min = number_list[i] number_list[index_of_min] = number_list[low] number_list[low] = min choose_sort_recursive(number_list, low+1, high) x = [20, 20, 2, 3, 2, 5, 6, 1, -2, 3, 14, 12, 3, -1, -1] choose_sort_recursive(x) p 4000 rint(x)
2. 插入排序
第一轮排好前1个数(即0位置的数, 当然此时只有一个数,无需比较即完成),第二轮排好前2个数(即0-1位置的数),第三轮排好前3个数(即0-2位置的数);依此进行n轮,完成排序。
[code]def insert_sort(number_list): n = len(number_list) for i in range(n): current = number_list[i] for j in range(i-1, -1, -1): if current < number_list[j]: number_list[j + 1] = number_list[j] number_list[j] = current x = [20, 20, 2, 3, 2, 5, 6, 1, -2, 3, 14, 12, 3, -1, -1] insert_sort(x) print(x)
3. 冒泡排序
第一轮最大的数放到底(即放在n-1位置),第二轮次大的数放在n-2位置;依此进行n-1轮,完成排序。就像泡泡不断冒出一样,故称为冒泡排序。
[code]def bubble_sort(number_list): n = len(number_list) for i in range(n - 1): for j in range(n - i - 1): if number_list[j] > number_list[j + 1]: temp = number_list[j] number_list[j] = number_list[j + 1] number_list[j + 1] = temp x = [20, 20, 2, 3, 2, 5, 6, 1, -2, 3, 14, 12, 3, -1, -1] bubble_sort(x) print(x)
可对冒泡排序进行改进,若在某一轮中已完成排序,即无数据位置的变动,那么不需要再进行其余轮次的比较了。
[code]def bubble_sort_improve(number_list): n = len(number_list) nextRound = True if nextRound: for i in range(n - 1): nextRound = False for j in range(n - i - 1): if number_list[j] > number_list[j + 1]: temp = number_list[j] number_list[j] = number_list[j + 1] number_list[j + 1] = temp nextRound = True x = [20, 20, 2, 3, 2, 5, 6, 1, -2, 3, 14, 12, 3, -1, -1] bubble_sort_improve(x) print(x)
关于选择排序、插入排序、冒泡排序,可以参考java实现一个选择、冒泡、插入排序的简单演示器,我在那里编写了一个简单的动态演示器。
4. 归并排序*
这是一个递归的过程。将n个数分为左、右两部分,每个部分分别进行排序,再将已排好序的左右两部分进行“整合排序”,就完成了最终的排序。这样分割的部分排序呢?使用同样的方法,将其分割、分别排序、整合排序,即一个递归的过程。
[code]# 递归过程 def merge_sort(number_list): if len(number_list) > 1: mid = int(len(number_list) / 2) left = number_list[:mid] right = number_list[mid:] merge_sort(left) merge_sort(right) merge(left, right, number_list) # 整合排序 def merge(left, right, list): index_left = 0 index_right = 0 index_list = 0 while index_left < len(left) and index_right < len(right): if left[index_left] < right[index_right]: list[index_list] = left[index_left] index_list += 1 index_left += 1 else: list[index_list] = right[index_right] index_list += 1 index_right += 1 while index_left < len(left): list[index_list] = left[index_left] index_list += 1 index_left += 1 while index_right < len(right): list[index_list] = right[index_right] index_list += 1 index_right += 1 x = [20, 20, 2, 3, 2, 5, 6, 1, -2, 3, 14, 12, 3, -1, -1] merge_sort(x) print(x)
这里我的例子是二路归并,即每次分割为两部分,当然也可进行多路归并,每次分割成多部分。
5. 快速排序*
这是一个递归的过程。选择某个数作为关键数(pivot),这里我们选取第一个数作为关键数,然后将其放在它“应该在的位置”,即该位置左边的数都不大于它,该位置右边的数都不小于它。这样列表分为三个部分:左部分、已放好的关键数、右部分。对左部分即右部分,使用同样的方法排序,即选关键数,并将其放在应该在的位置,即一个递归过程。
[code]def quick_sort(number_list, low, high): if low < high: pivot_index = divide(number_list, low, high) quick_sort(number_list, low, pivot_index-1) quick_sort(number_list, pivot_index+1, high) def divide(number_list, low, high): pivot = number_list[low] pivot_index = low + 1 while pivot_index <= high: if number_list[pivot_index] < pivot: pivot_index += 1 else: if number_list[high] >= pivot: high -= 1 else: temp = number_list[pivot_index] number_list[pivot_index] = number_list[high] number_list[high] = temp pivot_index += 1 high -= 1 number_list[low] = number_list[pivot_index-1] number_list[pivot_index-1] = pivot return pivot_index-1 x = [20, 20, 2, 3, 2, 5, 6, 1, -2, 3, 14, 12, 3, -1, -1] quick_sort(x, 0, len(x)-1) print(x)
6. 堆排序*
我们定义这样的一个二叉树结构:,每个结点的数都不小于它的子树中的数;不是最后一次层的层必须铺满,最后一层可以不铺满但必须“向左对齐”;
我们向树中添加或者删除数时,都必须进行调整以保证树的结构满足要求。这样的树中,顶点的数是最大的,因此我们将一组数添加到这样的树结构中后,不断地获取顶点的数。由于每次获取后,树的结构都将进行调整,所以我们获取的数即是由大到小排序的了。
我们可以用列表(数组)表示这样的二叉树:0位置表示第一层,1-2位置表示第二层,3-6位置表示第三层……。这样i位置的数在树结构中的左右孩子(如果存在的话)分别位于2*i+1和2*i+2位置;j位置的数在树结构中的父结点位于(j-1)/2位置。
我们定义一个类,类中的列表用来表示树,并定义相应的函数用于向树中添加或者移除数。
[code]class Heap(): def __init__(self, number_list): self.number_list = [] for num in number_list: self.add(num) def add(self, num): self.number_list.append(num) current = self.get_size() - 1 while current > 0: parent = int((current - 1) / 2) if (self.number_list[current] > self.number_list[parent]): temp = self.number_list[current] self.number_list[current] = self.number_list[parent] self.number_list[parent] = temp current = parent else: break def remove(self): if self.get_size() == 0: return max = self.number_list[0] if self.get_size() > 1: self.number_list[0] = self.number_list.pop() elif self.get_size() == 1: self.number_list.pop() current = 0 while current < self.get_size(): left = 2 * current + 1 right = 2 * current + 2 if left >= self.get_size(): break index_max = left if right < self.get_size(): if self.number_list[right] > self.number_list[left]: index_max = right if self.number_list[current] < self.number_list[index_max]: temp = self.number_list[current] self.number_list[current] = self.number_list[index_max] self.number_list[index_max] = temp current =index_max else: break return max def get_size(self): return len(self.number_list) def get_list(self): return self.number_list x = [20, 20, 2, 3, 2, 5, 6, 1, -2, 3, 14, 12, 3, -1, -1] x_heap = Heap(x) for i in range(len(x) - 1, -1, -1): x[i] = x_heap.remove() x
7. 桶排序*
桶排序可用来对非负整数进行排序。设一组非负整数中最大的值为k,我们建立k+1个桶并按序编号。遍历这组非负整数,若数大小为i,则将其放入i号桶中。最后按序从桶中依次取出所有的数,即完成排序。
[code]def bucket_sort(number_list): bucket = [[]] size = max(number_list) for i in range(size): bucket.append([]) for integer in number_list: bucket[integer].append(integer) for i in range(len(number_list) - 1): number_list[i] = -1 count = 0 for i in bucket: for j in i: number_list[count] = j count += 1 x = [25, 25, 7, 8, 7, 10, 11, 6, 3, 8, 19, 17, 8, 4, 4] bucket_sort(x) x
我们可以比较不同算法的排序时间,以及python列表自带排序函数的排序时间。
[code]####### 比较不同算法的效率 import random import time NUMBER = 10000 large_list = [] for i in range(NUMBER): large_list.append(int(random.uniform(0, 1)*100000) ) # 选择排序 choose_list = large_list[:] start_time = int(round(time.time())) choose_sort(choose_list) end_time = int(round(time.time())) choose_sort_time = end_time - start_time # 插入排序 insert_list = large_list[:] start_time = int(round(time.time())) insert_sort(insert_list) end_time = int(round(time.time())) insert_sort_time = end_time - start_time # 冒泡排序 bubble_list = large_list[:] start_time = int(round(time.time())) bubble_sort(bubble_list) end_time = int(round(time.time())) bubble_sort_time = end_time - start_time # 改进的冒泡排序 bubble_improve_list = large_list[:] start_time = int(round(time.time())) bubble_sort_improve(bubble_improve_list) end_time = int(round(time.time())) bubble_sort_improve_time = end_time - start_time # 归并排序 NUMBER = 100000 large_list = [] for i in range(NUMBER): large_list.append(int(random.uniform(0, 1)*100000) ) merge_list = large_list[:] start_time = int(round(time.time()) * 1000) merge_sort(merge_list) end_time = int(round(time.time()) * 1000) merge_sort_time = end_time - start_time # 快速排序 quick_list = large_list[:] start_time = int(round(time.time()) * 1000) quick_sort(quick_list, 0, len(merge_list)-1) end_time = int(round(time.time()) * 1000) quick_sort_time = end_time - start_time # 堆排序 heap_list = large_list[:] start_time = int(round(time.time()) * 1000) list_heap = heap.Heap(heap_list) for i in range(len(heap_list) - 1, -1, -1): heap_list[i] = list_heap.remove() end_time = int(round(time.time()) * 1000) heap_sort_time = end_time - start_time # 自带排序 list2 = large_list[:] start_time = int(round(time.time()) * 1000) list2.sort() end_time = int(round(time.time()) * 1000) self_sort_time = end_time - start_time print("choose_sort: " + str(choose_sort_time) + " seconds") print("insert_sort: " + str(insert_sort_time) + " seconds") print("bubble_sort: " + str(bubble_sort_time) + " seconds") print("bubble_sort_imporove: " + str(bubble_sort_improve_time) + " seconds") print("merge_sort: " + str(merge_sort_time) + " milliseconds") print("quick_sort: " + str(quick_sort_time) + " milliseconds") print("heap_sort: " + str(heap_sort_time) + " milliseconds") print("self_sort: " + str(self_sort_time) + " milliseconds")阅读更多
- 刚接触编程的同学可以看看的几个编程练习(python实现)(四)
- 刚接触编程的同学可以看看的几个编程练习(python实现)(二)
- 刚接触编程的同学可以看看的几个编程练习(python实现)(一)
- 刚接触编程的同学可以看看的几个编程练习(python实现)(三)
- python编程练习---栈的实现
- Python编程练习:编程实现恺撒密码
- 自己学习编程时间比较短,现在把一下自己以前刚刚接触C++时的程序上传一下,有空可以看看
- 第一次尝试用python来编程实现“helloworld”,顺利成功,过程中遇到几个小问题
- python编程练习---队列的实现
- 【编程练习】二叉树的反转,Java和Python实现
- python编程练习---一行代码实现计算器功能
- 【编程练习】快速排序,Java和Python实现
- python编程练习,实现9、9乘法口诀
- python核心编程 第六章练习6-2
- 《Python核心编程》第二版第162页第六章练习 续六 -Python核心编程答案-自己做的-
- 在Revit里面是否可以编程实现停靠的对话框?(暂不能)
- 看看360的同学日常是怎么使用python的
- 《Python核心编程》第二版第36页第二章练习 续一 -Python核心编程答案-自己做的-
- socket编程实现HTTP下载 思路 ,未实现的 可以直接用 微软的 wininet 库 (转载)
- Python GUI编程各种实现的对比