日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python算法题排序_python-数据结构与算法- 面试常考排序算法题-快排-冒泡-堆排-二分-选择等...

發布時間:2024/7/23 python 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python算法题排序_python-数据结构与算法- 面试常考排序算法题-快排-冒泡-堆排-二分-选择等... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

算法可視化網站推薦---->visualgo

0.面試題中的排序算法

一些排序算法可能在工作中用的會比較少,但是面試卻是不得不面對的問題。算法有助于提高我們對數據結構的理解以及提高自己的邏輯能力,沒事刷刷真的不錯。

1.快排

面試最推薦而且也是寫的最多的

快排的思路是分而治之,相當于我每次去將一個數歸為,直到所有的數都歸為了,那么這個排序也就成功了。

快排第一種思路:(這個思路參考下,不要寫)

平均時間復雜度

最好時間復雜度

最壞時間復雜度

空間復雜度

排序方式

O(nlogn)

O(nlogn)

O(n2)

O(nlogn)

in-place

import random

def quickSort(nums): # 這種寫法的平均空間復雜度為 O(nlogn),時間復雜度為O(nlogn)

if len(nums) <= 1:

return nums

mid = nums[0] # 基準值

left = [nums[i] for i in range(1, len(nums)) if nums[i] < mid]

right = [nums[i] for i in range(1, len(nums)) if nums[i] >= mid]

return quickSort(left) + [mid] + quickSort(right)

li = list(range(100))

random.shuffle(li)

print(li)

print(quickSort(li))

這個利用到了遞歸,分而治之,但是這個算法的空間復雜度較高,有可以優化的點。在做算法題的時候,對于列表字典這些可變數據結構,一定要明白如何去利用這些數據結構本身的內存而不是再去開辟很多新的內存。

快排第二種思路:

平均時間復雜度

最好時間復雜度

最壞時間復雜度

空間復雜度

排序方式

O(nlogn)

O(nlogn)

O(n2)

O(log)

in-place

import random

class Solution(object):

"""

快排

時間復雜度為O(nlogn),最差情況為O(n2)

空間復雜度為O(logn)

"""

def partition(self, li: list, left, right):

tmp = li[left]

while left < right:

while left < right and li[right] >= tmp:

right -= 1

li[left] = li[right]

while left < right and li[left] <= tmp:

left += 1

li[right] = li[left]

li[left] = tmp

return left

def quick_sort(self, li, left, right):

if left < right:

mid = self.partition(li, left, right)

self.quick_sort(li, left, mid - 1)

self.quick_sort(li, mid + 1, right)

li = list(range(100))

random.shuffle(li)

print(li)

solution = Solution()

print(solution.quick_sort(li, 0, len(li) - 1))

print(li)

與第一種方法不同的點就是在于對空間的利用,利用了li本身的內存空間。

寫在同一個函數里

如何把他們寫在同一個函數里并且有一個new idea,在找到兩邊各一個不屬于各自位置的值后,進行交換。

def quick_sort(li, start, end):

if start >= end:

return

left, right = start, end

tmp = li[left]

while left < right:

# 設置一個基準點

while left < right:

while left < right and li[right] >= tmp: # 至少要一個等號,不然會出現死循環

right -= 1

li[left] = li[right]

while left < right and li[left] <= tmp: # 因為如果沒有一邊有等號,當列表中有兩個相同值的時候,就無法跳出循環

left += 1

li[right] = li[left]

li[left] = tmp

quick_sort(li, start, left - 1)

quick_sort(li, left + 1, end)

if __name__ == '__main__':

import random

li = list(range(100))

li.append(55)

random.shuffle(li)

print(li)

print(quick_sort(li, 0, 99))

print(li)

順便把參數數量也降低一下:

def quick_sort(li):

def _quick_sort(li, start, end):

if start >= end:

return

left, right = start, end

tmp = li[left]

while left < right:

# 設置一個基準點

while left < right:

while left < right and li[right] >= tmp: # 至少要一個等號,不然會出現死循環

right -= 1

li[left] = li[right]

while left < right and li[left] <= tmp: # 因為如果沒有一邊有等號,當列表中有兩個相同值的時候,就無法跳出循環

left += 1

li[right] = li[left]

li[left] = tmp

_quick_sort(li, start, left - 1)

_quick_sort(li, left + 1, end)

_quick_sort(li, 0, len(li)-1)

2.冒泡排序

平均時間復雜度

最好時間復雜度

最壞時間復雜度

空間復雜度

排序方式

O(n2)

O(n)

O(n2)

O(1)

in-place

理解的關鍵點在于左半部分是有序區。

冒泡作為最簡單的排序算法之一,面試的時候萬不得已(其他的都記不住了),還是不要寫。寫個快排能好多了。

import random

class Solution(object):

"""

冒泡排序

"""

@staticmethod

def bubble_sort(li):

for i in range(len(li) - 1): # 交換的次數

flag = True # flag的作用是當這個序列就是一個升序(這邊排的是升序),那么久可以降低時間復雜度到O(n)

for j in range(len(li) - i - 1): # 剩余需要交換的元素

if li[j] > li[j + 1]:

li[j], li[j + 1] = li[j + 1], li[j]

flag = False

if flag:

return li

return li

li = list(range(100))

random.shuffle(li)

print(li)

solution = Solution()

solution.bubble_sort(li)

print(li)

3.選擇排序

平均時間復雜度

最好時間復雜度

最壞時間復雜度

空間復雜度

排序方式

O(n2)

O(n2)

O(n2)

O(1)

in-place

選擇排序主要需要注意點是左邊部分是有序區。

也不推薦寫,時間復雜度高,效率低,太簡單了。

import random

class Solution(object):

"""

選擇排序

"""

def select_sort(self, li):

for i in range(len(li) - 1):

min_pos = i

for j in range(i+1, len(li)): # 左部分是有序區

if li[min_pos] > li[j]:

min_pos = j

li[i], li[min_pos] = li[min_pos], li[i]

return li

li = list(range(100))

random.shuffle(li)

print(Solution().select_sort(li))

4.插入排序

插入排序如同打撲克一樣,每次將后面的牌插到前面已經排好序的牌中。使得左半部分為有序區域。

平均時間復雜度

最好時間復雜度

最壞時間復雜度

空間復雜度

排序方式

O(n2)

O(n2)

O(n2)

O(1)

in-place

import random

def insert_sort(li):

for i in range(1, len(li)):

# i 表示趟數 還表示摸到牌的位置

j = i - 1 # 取到摸到牌的前一張,也就是有序位置的最后一張牌

tmp = li[i]

while j >= 0 and li[j] > tmp:

# 兩個終止條件: 1. j==-1 2. j位置的值小于等于tmp

li[j + 1] = li[j]

j -= 1

li[j + 1] = tmp

li = list(range(10000))

random.shuffle(li)

insert_sort(li)

print(li)

5.堆排序(Heap Sort)

import random

def sift(li, low, high):

"""

堆調整程序

:param li:

:param low:

:param high:

:return:

"""

tmp = li[low]

i = low

j = 2 * i + 1

while j <= high: # 第一個退出條件:j不存在

if j + 1 <= high and li[j + 1] > li[j]: # 如果右孩子存在并且右孩子比左孩子大

j += 1 # j指向右孩子

if li[j] > tmp:

li[i] = li[j]

i = j

j = 2 * i + 1

else: # 第二個退出條件:j位置的值比tmp小

break

li[i] = tmp

def heap_sort(li):

# 1. 建堆

n = len(li)

for i in range(n // 2 - 1, -1, -1): # i表示遍歷的low

sift(li, i, n - 1) # low:i high:統一寫成最后一個位置對正確性沒有影響

# 2. 挨個出數:退休 棋子 調整

for i in range(n - 1, 0, -1): # i 表示當前位置堆的high

li[i], li[0] = li[0], li[i]

sift(li, 0, i - 1)

# print(li)

li = list(range(100000))

random.shuffle(li)

heap_sort(li)

print(li)

6.二分查找

二分查找非常簡單,是建立在列表有序的情況下,利用二分法不斷逼近目標值的。

def binary_search(li, target):

left = 0

right = len(li) - 1

while left <= right:

mid = (right - left) // 2 # 取一個中間值

if target > li[mid]:

left = mid + 1 # 如果比目標值比中位值還要大,調整右邊界指針

elif target < li[mid]:

right = mid - 1 # 如果比目標值比中位值要小,調整左邊界指針

else:

return mid

return -1

算法的穩定性

選擇排序、快速排序、希爾排序、堆排序不是穩定的排序算法,而冒泡排序、插入排序、歸并排序和基數排序是穩定的排序算法

總結

以上是生活随笔為你收集整理的python算法题排序_python-数据结构与算法- 面试常考排序算法题-快排-冒泡-堆排-二分-选择等...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。