您的位置:首页 > 编程语言 > Python开发

python 学习(排序)

2020-01-14 07:33 155 查看

这里写自定义

python 学习(排序)

  1. 时间复杂度为N^2: 冒泡排序,插入排序,选择排序。
  2. 时间复杂度为NlogN:堆排序,快速排序, 归并排序。
  3. 时间复杂度基于数据大小:计数排序,基数排序。

常用的排序算法,使用python实现。

冒泡排序

def buble(num):
for i in range(len(num)):
count = 0
for j in range(len(num)-1-i):
if num[j] > num[j+1]:
num[j], num[j+1] = num[j+1], num[j]
count += 1
if count == 0:
break
return num

每次将元素从底到顶遍历,如果当前元素比下一个元素大就交换,使得最大的元素在顶部。每次遍历顶部减一, 直至底到顶只有一个元素。 P.S如果一次遍历中没有发生交换,则该数组已经有序。

插入排序

def insert(num):
n = len(num)

for i in range(n-1):
for j in range(i+1, 0, -1):
if num[j] < num[j-1]:
num[j], num[j-1] = num[j-1], num[j]
else:
break
return num

从底部向顶部遍历,如果当前元素小于前一个元素就交换,该次遍历结束至底部。当底部顶部重合时结束排序。

选择排序

def select(num):
n = len(num)

for i in range(n):
minIndex = i
for j in range(i, n):
if num[minIndex] > num[j]:
minIndex = j
num[i], num[minIndex] = num[minIndex], num[i]
return num

堆排序

从底部开始,遍历数组,保留数组中最小的数并与数组底部交换。数组底部+1,直至底部顶部重合。

def heapSort(nums):
if len(nums) < 2:
return nums

for i in range(len(nums)):
heapInsert(nums, i)
size = len(nums)-1
while size > 0:
nums[size] = heapPop(nums, size)
size -= 1
return nums

def heapInsert(nums, i):
while nums[i] > nums[(i-1) // 2] and i > 0:
nums[i], nums[(i-1) // 2] = nums[(i-1) // 2], nums[i]
i += (i-1) // 2

def heapPop(nums, size):
t = nums[0]
nums[0] = nums[size]
index = 0
left = index*2 + 1
right = index*2 + 2
while left < size-1:
largest = right if right < size and nums[right] > nums[left] else left
largest = index if nums[index] > nums[largest] else largest
if index == largest:
break
nums[index], nums[largest] = nums[largest], nums[index]
index = largest
left = index*2 + 1
right = index*2 + 1
return t

构建小根堆(堆顶为最小值)。将数组放入堆中,再每次弹出堆顶,直至堆空。

快速排序

def quick(num):
if len(num) < 2:
return num
quick_sort(num, 0, len(num)-1)
return num

def quick_sort(num, l, r):
if l < r:
p = partition(num, l, r)
quick_sort(num, l, p[0])
quick_sort(num, p[1], r)

def partition(num, l, r):
less = l-1
more = r
index = l

while index < more:
if num[index] < num[more]:
less += 1
num[index], num[less] = num[less], num[index]
index += 1
elif num[index] > num[more]:
more -= 1
num[more], num[index] = num[index], num[more]
else:
index += 1
num[index], num[r] = num[r], num[index]
return [less, more]

主要核心是partition过程。partition根据最后一个值,划分出比该值大的区域和比该值小的区域。分割数组,划分partition区域,直至不能划分为止。

归并排序

def merge(num):
if len(num) < 2:
return num

mid = len(num) // 2
left = merge(num[:mid])
right = merge(num[mid:])
return merge_sort(left, right)

def merge_sort(left, right):
c = []
l = 0
r = 0

while l < len(left) and r < len(right):
if left[l] <= right[r]:
c.append(left[l])
l += 1
else:
c.append(right[r])
r += 1

if l == len(left):
for i in right[r:]:
c.append(i)
else:
for i in left[l:]:
c.append(i)
return c

分而治之思想,分化两侧,直至两侧长度为1。再将两侧合并在一起,由于每次归并时,两侧内容都是有序的,节省了时间。

计数排序

def countNums(nums):
n = len(nums)
res = [None]*n

for i in range(n):
p = 0
for j in range(n):
if nums[i] > nums[j]:
p += 1
res

= nums[i] return res

[p]统计数组中其他数比该数大的个数p(越小的数,p越小)。p代表该数的排序后的位置。

基数排序

def radixSort(nums):
i = 0
n = 1

max_ = max(nums)
num_t = [int(k) for k in list(str(max_))]
n = len(num_t)

while i < n:
bucket = {}
for x in range(10):
bucket[x] = []
for x in nums:
radix =(x / (10**i)) % 10
bucket[radix].append(x)
j = 0
for k in range(10):
if len(bucket[k]) > 0:
for y in bucket[k]:
nums[j] = y
j += 1
i +=1
return nums

按每一位大小排序,从低位排到高位。

稳定性

根据排序前后相对次序是否变化将算法分为,稳定和不稳定。P.S:即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。(引用百度百科)
不稳定排序:选择排序、快速排序、希尔排序、堆排序。

稳定排序:冒泡排序、插入排序、归并排序和基数排序。

  • 点赞
  • 收藏
  • 分享
  • 文章举报
qq_27295149 发布了29 篇原创文章 · 获赞 1 · 访问量 367 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: