要求:对某一无序列表进行排序,使其按照从小到大排序,不使用python内建函数。
假设给定的列表为:
list=[1,2,3,4,5,6,9,8,7]
1、解题思路
看到题目首先脑子里想到的就是前两个数比较大小,如果第一个数大于第二个数,就交换两个数的位置,以此类推知道所有的数都比较完,逻辑如下:
if list[0] > list[1]:
temp = list[1] #先用一个变量把list[1]存起来,用于交换
list[1] =list[0]#前两位交换位置
list[0] = temp
上面做了两个数的比较,后面按照list的索引逐步往后进行循环,n个数字两两比较需要循环n-1次,第一次比较会把当前循环的最大值放到后面,第二次比较时因为最后面已经是最大值了,所以比较到n-2。以此类推,每一次循环都会减少待比较值,直到剩余最后两个数比较。
2、代码实现
list=[1,2,3,4,5,6,9,8,7]
for i in range(len(list)):##第一层循环n-1次
for j in range(len(list)-1-i):#第二层循环n-1-i次
if list[j] > list[j+1]:
temp = list[j+1] #先用一个变量把list[1]存起来,用于交换
list[j+1] =list[j]#前两位交换位置
list[j] = temp
print(list)
>> [1,2,3,4,5,6,7,8,9]
3、优化思路
从上面代码分析,第一层循环第一次比较根本不用进入第二层判断,因为1已经是最小的数字,不会和任何其他数字交换,2,3,4,5,6同理,如果把这部份循环省略可进一步提升运算速度,为对比明显,增加变量count_for,count_if分别记录进入到第二层循环的次数和判断的次数,增加flag变量记录单签循环是否发生交换,如本次没有交换,终止当前循环。
优化前代码:
list=[1,2,3,4,5,6,9,8,7]
count_for=0
count_if=0
for i in range(len(list)):
for j in range(len(list)-1-i):
count_for += 1 #每进入一次循环+1
if list[j] > list[j+1]:
count_if += 1 # 每进入一次判断+1
temp = list[j+1]
list[j+1] =list[j]
list[j] = temp
print('循环次数=',count_for)
print('判断次数=',count_if)
>> 循环次数= 36
>> 判断次数= 3
优化后代码:
list=[1,2,3,4,5,6,9,8,7]
count_for=0
count_if=0
for i in range(len(list)):
flag = False #每次循环前默认交换标识为未交换
for j in range(len(list)-1-i):
count_for += 1 #每进入一次循环+1
if list[j] > list[j+1]:
count_if += 1 # 每进入一次判断+1
temp = list[j+1]
list[j+1] =list[j]
list[j] = temp
flag = True #如果发生交换,变更交换状态
if flag == False : #如果当前循环为发生交换,跳出当前循环
break
print('循环次数=',count_for)
print('判断次数=',count_if)
>> 循环次数= 21
>> 判断次数= 3
以上。