def bubble_sort(a_list):
for pass_num in range(len(a_list) - 1, 0, -1):
for i in range(pass_num):
if a_list[i] > a_list[i+1]:
a_list[i+1], a_list[i] = a_list[i], a_list[i+1]
a_list = [54, 26, 93, 17, 77, 31, 44, 55, 20]
bubble_sort(a_list)
print(a_list)
Suppose you have a bunch of music on your computer. For each artist, you have a play count.
One way is to go through the list and find the most-played artist. Add that artist to a new list.
To find the artist with the highest play count, you have to check each item in the list. This takes $O(n)$ time, as you just saw. So you have an operation that takes $O(n)$ time, and you have to do that n times:
This takes $O(n × n)$ time or $O(n^2)$ time.
def selection_sort(a_list):
for fill in range(len(a_list) - 1, 0, -1):
pos_max = 0
for location in range(1, fill + 1):
if a_list[location] > a_list[pos_max]:
pos_max = location
a_list[pos_max], a_list[fill] = a_list[fill], a_list[pos_max]
def insertion_sort(a_list):
for index in range(1, len(a_list)):
current_value = a_list[index]
position = index
while position > 0 and a_list[position - 1] > current_value:
a_list[position] = a_list[position - 1]
position = position - 1
a_list[position] = current_value
def merge_sort(a_list):
print("Splitting ", a_list)
if len(a_list) > 1:
mid = len(a_list) // 2
left_half = a_list[:mid]
right_half = a_list[mid:]
merge_sort(left_half)
merge_sort(right_half)
i = 0
j = 0
k = 0
#continue
while i < len(left_half) and j < len(right_half):
if left_half[i] < right_half[j]:
a_list[k] = left_half[i]
i = i + 1
else:
a_list[k] = right_half[j]
j = j + 1
k = k + 1
while i < len(left_half):
a_list[k] = left_half[i]
i = i + 1
k = k + 1
while j < len(right_half):
a_list[k] = right_half[j]
j = j + 1
k = k + 1
print("Merging ", a_list)
Base case
An array with two elements is pretty easy to sort, too.
What about an array of three elements?
We use D&C to solve this problem. Let's pick a pivot at first, say, 33.
This is called partitioning. Now you have:
A sub-array of all the numbers less than the pivot
The pivot
A sub-array of all the numbers greater than the pivot
If the sub-arrays are sorted, then you can combine the whole thing like this—left array + pivot + right array—and you get a sorted array.
Suppose you have this array of five elements.
For example, suppose you pick 3 as the pivot. You call quicksort on the sub-arrays.
Quicksort is unique because its speed depends on the pivot you choose.
Actually, the big O of the quick sort algorithm depends on the pivot you pick.
In the best case, the big O of quick sort is $O(nlogn)$. However, in the worst case, the big O of it turns to be $O(n^2)$.
Why?
Worst Case
Best Case
The average case is the best case, if you pick pivot randomly.
# 原始课程数据,每个元组包含:(课程名, 开始时间, 结束时间)
courses = [("数学", 9, 10),("物理", 9.5, 10.5),("化学", 10, 11),
("生物", 10.5, 11.5),("英语", 11, 12),("历史", 8, 9),
("地理", 12, 13),("政治", 13, 14),("语文", 12.5, 13.5)]
# 按结束时间排序
sorted_courses = sorted(courses, key=lambda x: x[2]) # x[2] 是结束时间
# 贪婪选择不冲突的课程
selected = []
earliest_end = 0
for name, start, end in sorted_courses:
if start >= earliest_end:
selected.append((name, start, end))
earliest_end = end
# 输出选中的课程
for course in selected:
print(course)
def greedy_coin_change(coins, amount):
coins.sort(reverse=True) # 从大到小排序
result = []
for coin in coins:
while amount >= coin:
amount -= coin
result.append(coin)
return result if amount == 0 else None
# 示例:标准货币系统
coins = [1, 5, 10, 25] # 美分
amount = 63
print(greedy_coin_change(coins, amount))
# 输出: [25, 25, 10, 1, 1, 1]
# 示例:标准货币系统
coins = [1, 5, 10, 21, 25] # 如果有21美分这个选项
amount = 63
print(greedy_coin_change(coins, amount))
# 输出: [25, 25, 10, 1, 1, 1] #贪婪算法失败,最优是21*3