排序总结-python

目录

排序学习python

二叉搜素

选择排序selectSort

冒泡排序bubbleSort

基础版:(复杂度固定用for)

改良版:(标志是否交换,有最好情况)

应用

插入排序insertSort

快速排序quickSort

应用:

归并排序mergeSort


排序学习python

二叉搜素

def binarySearch(target,sortedList):
    """二分查找有序数组中目标值"""
    left = 0
    right = len(sortedList) - 1
    while left <= right:
        midPoint = (left + right) // 2
        if target == sortedList[midPoint]:
            return midPoint
        elif target < sortedList[midPoint]:
            right = midPoint - 1
        else:
            left = midPoint + 1
    return -1

binarySearch(44 ,[1,3,4,7,20,33,34,44,55,66,77])

选择排序selectSort

# 第一步:遍历每一个位置,认为每个位置即为从此位置往后中最小的值
# 第二步:在第一步的位置以后去找最小值位置
# 第三步:第一步位置与最小值位置比较,不一样就交换
# 时间复杂度:O(n^2)
# For循环:
def selectSort(s):
    for i in range(len(s)):
        minPoint = i
        for j in range(i+1,len(s)):
            if s[j] < s[minPoint]:
                 minPoint = j
        if i != minPoint:
            s[i], s[minPoint] = s[minPoint], s[i]                           
    return s

冒泡排序bubbleSort

思想:每次遍历前后比较会把最大的数交换到最后面的位置

I:就是每次循环来控制范围的

J:在i控制的范围内做交换

时间复杂度:O(n^2)

基础版:(复杂度固定用for)

#For循环:
#(1)
def bubbleSort(s):
    for i in range(len(s)-1):
        for j in range(len(s)-1-i):
            if s[j] > s[j+1]:
                s[j], s[j+1] = s[j+1], s[j]
    return s


lis = [85, 28 , 53, 72, 14, 11, 31, 52, 69, 17, 75, 12, 31, 41, 83 ]
bubbleSort(lis)


#(2)
def bubbleSort(s):
     for i in range(len(s)-1,0,-1):
         for j in range(i):
             if s[j] > s[j+1]:
                 s[j], s[j+1] = s[j+1], s[j]
     return s


lis = [85, 28 , 53, 72, 14, 11, 31, 52, 69, 17, 75, 12, 31, 41, 83 ]
bubbleSort(lis)
#while循环:
#(1)
def bubbleSort(s):
    i = 0
    while i < len(s)-1:
        j = 0
        while j < len(s)-i-1:
            if s[j] > s[j+1]:
                s[j], s[j+1] = s[j+1], s[j]
            j += 1
        i += 1
    return s


lis = [85, 28 , 53, 72, 14, 11, 31, 52, 69, 17, 75, 12, 31, 41, 83 ]
bubbleSort(lis)


#(2)
def bubbleSort(s):
     i = len(s) - 2
     while i > 0:
         j = 0
         while j < i:
             if s[j]>s[j+1]:
                 s[j],s[j+1] = s[j+1],s[j]
             j += 1
         i -= 1
     return s


lis = [85, 28 , 53, 72, 14, 11, 31, 52, 69, 17, 75, 12, 31, 41, 83 ]
bubbleSort(lis)

改良版:(标志是否交换,有最好情况)

def bubbleSort(s):
     for i in range(len(s)-1):
         ischange = 0#标志是否要交换,初始为不交换
         for j in range(len(s)-1-i):
             if s[j]>s[j+1]:
                 s[j],s[j+1]=s[j+1],s[j]
                 #print(ischange)
                 ischange = 1#交换操作后置1
         if not ischange :#如果没有交换说明已经排序好了
             print(i,j,ischange)
             return s
     return s

java版本

import java.util.Arrays;

public class Test1 {
    public static int[] bubbleSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            boolean flag = true;
            for (int j = 0; j < arr.length - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    flag = false;
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            if (flag) {
                break;
            }
        }
        return arr;
    }

    public static void main(String[] args) {
        int[] res = { 85, 28, 53, 72, 14, 11, 31, 52, 69, 17, 75, 12, 31, 41, 83 };
        int[] r = bubbleSort(res);
        System.out.println(Arrays.toString(r));
    }
}

应用

leetcode:力扣 

插入排序insertSort

插入排序的主要思想是每次取一个列表元素与列表中已经排序好的列表段进行比较,然后插入从而得到新的排序好的列表段,最终获得排序好的列表。

比如,待排序列表为[49,38,65,97,76,13,27,49],则比较的步骤和得到的新列表如下:

(带有背景颜色的列表段是已经排序好的,红色背景标记的是执行插入并且进行过交换的元素)

def insertSort(s):
     for i in range(1,len(s)):
         itemToInsert = s[i]
         j = i -1
         while j >= 0:
             if itemToInsert < s[j]:
                 s [j+1] = s[j]
                 j -= 1
             else:
                 break
         s[j+1] = itemToInsert
     return s

lis = [85, 28 , 53, 72, 14, 11, 31, 52, 69, 17, 75, 12, 31, 41, 83 ]
insertSort(lis)

快速排序quickSort

思想:给一个元素找到他最终的位置,比他大的放右边,比他小的放左边

def quick_sort(param, start, end):
    if start > end:
        return param
    mid = param[end]
    left, right = start, end
    while left < right:
        # mid存储了end, 可以覆盖,所以这里先移动start对应的left(反过来mid=param[start],那就先处理right)
        while left < right and param[left] <= mid:
            left += 1
        param[right] = param[left]  # 找到左边第一个比mid标杆大的数,扔到右边

        while left < right and param[right] > mid:
            right -= 1
        param[left] = param[right]  # 找到右边第一个比mid标杆小的数,扔到左边

    param[right] = mid  # 标杆的最后位置找到了---right的现在的位置
    quick_sort(param, start + 1, end)
    quick_sort(param, start, end - 1)  # 保证右边扔到左边的数很大没有找到自己的位置
    return param

s = [85, 28 , 53, 72, 14, 11, 31, 52, 69, 17, 75, 12, 31, 41, 83 ]  
quick_sort(s,0,len(s)-1)     

java版本

import java.util.Arrays;

public class Test1 {
    // 快排
    public static int[] quickSort(int[] arr, int start, int end){
        if (start > end) {
            return arr; 
        }
        int left = start;
        int right = end;
        int temp = arr[start];
        while (left < right) {
            while(left<right && arr[right]>temp){
                right--;
            }
            arr[left] = arr[right];
            while(left<right && arr[left]<=temp){
                left++;
            }
            arr[right]=arr[left];
        }
        arr[left]=temp;
        quickSort(arr, start+1, end);
        quickSort(arr, start, end-1);
        return arr;
    }

    public static void main(String[] args) {
        int[] res = { 85, 28, 53, 72, 14, 11, 31, 52, 69, 17, 75, 12, 31, 41, 83 };
        int[] r = quickSort(res,0,res.length-1);
        System.out.println(Arrays.toString(r));
    }
}

应用:

(1)leetcode:力扣

    def smallestK(self, arr: List[int], k: int) -> List[int]:
        if k >= len(arr):
            return arr
        if k == 0:
            return [] 
        def _quick_sort_k(nums, k, start, end):
            flag = nums[start]
            left, right = start, end

            while left < right:
                while left < right and nums[right] >= flag:
                    right -= 1
                nums[left] = nums[right]

                while left < right and nums[left] < flag:
                    left += 1
                nums[right] = nums[left]
            
            nums[left] = flag

            if left == k - 1: # 找到了
                return arr[: left+1]
            elif left < k - 1:
                return _quick_sort_k(nums, k, left+1, end)
            else:
                return _quick_sort_k(nums, k, start, left-1)
        
        return _quick_sort_k(arr, k, 0, len(arr)-1)

java版本

class Solution {
    public static void quickSort(int[] arr, int k, int start, int end){
        int temp = arr[start];
        int left = start;
        int right = end;
        while(left < right){
            while(left<right && arr[right]>temp){
                right--;
            }
            arr[left]=arr[right];

            while(left<right && arr[left]<=temp){
                left++;
            }
            arr[right]=arr[left];
        }
        arr[left] = temp;

        if(left == k-1){
            // 找到了位置
            return;
        }else{
            if(left < k-1){
                //说明还没有找够
                quickSort(arr, k, left+1, end);
            }else{
               //说明找的多了
                quickSort(arr, k, start, left-1);
            }
        }
        
    }
    public int[] smallestK(int[] arr, int k) {
        if(k>arr.length){
            return arr;
        }
        if(k==0){
            return new int[] {};
        }
        quickSort(arr,k,0,arr.length-1);
        int[] b = Arrays.copyOfRange(arr, 0, k);//存放返回元素
        return b;
        
    }
}

 (2)面试题:输出第k大的正整数,如果第K大正整数不存在,返回-1

                   这里我觉得需要规定输入的list都是由正整数组成,或者求第k大的数,因为题目下面的补充是这个意思

def search_k(nums, k):
    def _quick_sort(nums, k, start, end):
        # if start > end:  #找到最后的情况,这里应该走不到
        #    return -1
        flag = nums[start]
        left, right = start, end

        while left < right:
            while left < right and nums[right] <= flag:
                right -= 1
            nums[left] = nums[right]

            while left < right and nums[left] > flag:
                left += 1
            nums[right] = nums[left]

        nums[left] = flag

        if left == k - 1:  # left这个位置是这个flag的数的最终位置,左边是比他大的,右边比他小
            # 如果left的位置就是k-1,那就是第k大数了
            return nums[left]
        elif left < k - 1:
            return _quick_sort(nums, k, left + 1, end)
        else:
            return _quick_sort(nums, k, start, left - 1)

    if len(nums) < k: #第k大的数不存在
        return -1
    return _quick_sort(nums, k, 0, len(nums) - 1)


if __name__ == '__main__':
    nums = [4, 2, 1, 3, 5, 6, 5, 6]
    print(search_k(nums, 5))

归并排序mergeSort

归并排序采用分而治之的原理:

一、将一个序列从中间位置分成两个序列;

二、在将这两个子序列按照第一步继续二分下去;

三、直到所有子序列的长度都为1,也就是不可以再二分截止。这时候再两两合并成一个有序序列即可。

时间复杂度: 最好最坏都是 O( n log n )

稳定性:稳定
缺点:每次拆分数组都要开辟新的数组, 每次合并数组都要开新数组,空间复杂度很大

# (1)排序一个list
def merge(left, right):
    res = []
    while left and right:
        if left[0] <= right[0]:
            res.append(left.pop(0))
        else:
            res.append(right.pop(0))

    res += left
    res += right
    return res


def merge_sort(param):
    if len(param) <= 1:
        return param
    mid = len(param) // 2
    left, right = param[:mid], param[mid:]
    res_left = merge_sort(left)
    res_right = merge_sort(right)
    return merge(res_left, res_right)
(2)链表中的归并排序
class Node():
    '''定义一个链表类'''
    def __init__(self,val,next =None):
        self.val = val
        self.next = next

#构造测试数据
head = None
for i in  range(1,6):
    head = Node(i,head)

#验证新建数据
res = head
while res:
    print(res.val)
    res = res.next


#链表排序
def sortList( head):
    """
    :type head: ListNode
    :rtype: ListNode
    """
    if head is None or head.next is None:
        return head
    pre = head
    slow = head
    quick = head
    while quick and quick.next:
        pre = slow
        slow = slow.next
        quick = quick.next.next
    left = head
    right = pre.next
    pre.next = None
    left = sortList(left)
    right = sortList(right)
    return merge(left,right)


 #归并排序   
def merge(left,right):
    res = Node(0)
    result = res
    while left  and right:
        if left.val < right.val:
            res.next = left
            left = left.next
        else:
            res.next = right
            right = right.next
        res = res.next
    if left:
        res.next = left
    if right:
        res.next = right
    return result.next

#调用函数
t = sortList( head)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值