python实现插入排序的两种方法

本文深入探讨了使用Python实现插入排序的两种方法:一种是在新列表中进行排序,另一种是在原列表基础上排序。详细介绍了每种方法的原理、所需存储空间及时间复杂度,通过具体代码示例帮助读者理解。

python实现插入排序

preparing for a satisfying offer-------重温算法 day 1

方法1:新开辟一个列表存储

这种方法需要一个新的、同样长度的列表存储空间。

原理

  1. 给定若干个待排序的数,先把这些数放到列表中;
  2. 先从这些数中拿出一个记为num1,放在一个新的列表的第一位;
  3. 再从剩下的数中拿出一个num2和num1比较,比num1大就放到num1后面,小则放在num1前面,此时需要先把num1后移一位,num2才能放到num1前面的空位上。
  4. 继续从剩下的数中拿出一个num3和num1,num2的有序列比较,并按大小插入,同样插入前需要把后面的数依次后移一位,从而将num3要插入的位置空出来;
  5. 同样的方法依次插入所有的数;
  6. 结束条件:原有列表中的所有数都已经插入到新列表中;

代码

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
lt=[49,38,65,97,76,13,27]
length=len(lt)
newlt=[49] #新开辟的存储位置

for i in lt[1:]:
    tag = False
    for j in range(0,len(newlt)):
        if i<newlt[j]:#比较大小,寻找插入位置,比较j次
            tag=True
            newlt.append(0)
            for k in range(len(newlt)-1,j,-1):#确定插入位置后,开始移动元素,移动length-j次
                newlt[k]=newlt[k-1]
            newlt[j]=i
            print(newlt)
            break#结束此次插入
    if not tag:
        newlt.append(i)

评价

插入排序本身的时间复杂度为O(n2),但这种方法还需要对原列表进行遍历。
另外这种方法所需的额外存储空间较大。但优点是比较容易理解。

方法2:在原列表的基础上进行排序

这种方法只可能需要一个较短长度的新列表存储空间。

原理

  1. 给定若干个待排序的数,先把这些数放到列表中;
  2. 每次取出这个列表的最后一位num;
  3. 从该列表的第一位开始和num进行比较,直到碰到比num大的第j位,则先把从第j位开始后面的都依次向后移一位,然后把num放在该列表的第j位。
  4. 若num值比前面其他的数都大,则不会产生移位,num依然在最后一位,因为每次取出这个列表的最后一位,所以这样以后都会循环取出num,为了避免这种情况,先把num拿出来存到一个新的列表中;
  5. 循环2,3或2,4步骤;
  6. 结束条件:循环次数达到原数组的长度数值;
  7. 将循环最后的结果——部分有序列表和暂存在新列表中的数拼接起来。

代码

#!/usr/bin/env python
# -*- coding:utf-8 -*-
lt=[49,38,65,97,76,13,27]
count=len(lt)#将数组长度存下来,作为迭代总次数
temp=[]#用来存储下面不会导致移位的‘大’数
while count:
    count-=1#每迭代一次,总次数减一,以此作为退出while循环的判断条件
    point = lt[-1]
    #每次拿出列表的最后一位作为接下来要插入的数,从而相比第一种方法,省去对原列表的循环
    tag = True
    #如果要插入的数是最大的,则其经过一轮比较后仍然会留在数组最后,
    # 此后就如此循环,所以要暂时把这个最大的数存到一个新的列表中。
    for i in range(0,len(lt)):
        if point<lt[i]:
            tag=False#证明正在比较的这个数不是最大的
            for j in range(len(lt)-1,i,-1):
                lt[j]=lt[j-1]
            lt[i]=point
            print(1,lt)
            break
    if tag:#证明正在比较的这个数是最大的
        temp.append(lt[-1])
        lt=lt[:-1]
        print(2,lt)
for k in range(len(temp)-1,-1,-1):#将存储在temp中的‘大’数倒序取出连接到已经排好序的数组后面
    lt.append(temp[k])
print(lt)

评价

这种方法有点儿绕,但是不需要对原有列表进行遍历,也只可能需要较短的新列表存储空间。

<think>我们被要求提供插入排序Python实现示例代码。根据引用[2]、[3]、[4]中提供的插入排序实现,我们可以总结出插入排序的基本思想:插入排序将数组分为有序区和无序区,初始时有序区只有一个元素(即数组的第一个元素),然后逐步将无序区的元素插入到有序区的适当位置,直到整个数组有序。插入排序的核心操作是:对于当前无序区的第一个元素(即待插入元素),从有序区的末尾开始向前扫描,找到相应位置并插入。根据引用[2]和[3]的代码示例,我们可以写出两种常见的插入排序实现方式:1.类似于引用[2]的方式:使用两层循环,外层循环遍历每个元素(从第二个元素开始),内层循环在有序区中从后往前比较,如果待插入元素小于当前比较的元素,则交换位置,直到找到合适的位置。2.类似于引用[3]的方式:在内层循环中使用while循环,从当前位置向前比较并交换(或移动)元素。另外,引用[4]中提到了插入排序类似于打扑克牌抽牌插入的过程。我们将提供两种实现方式,并解释其工作原理。注意:插入排序的时间复杂度为$O(n^2)$,空间复杂度为$O(1)$,是一种稳定的排序算法实现方式1(交换法):在每次内层循环中,如果当前元素比前一个元素小,就交换它们,并继续向前比较,直到不需要交换为止。实现方式2(移动法):先保存当前元素的值,然后从该元素的前一个位置开始向前比较,如果比当前元素大,就向后移动一位,直到找到合适的位置插入。我们通常使用移动法,因为它比交换法的赋值次数更少。下面我们分别给出这两种实现,并提供一个示例。</think>### Python 插入排序算法实现 插入排序是一种简单直观的排序算法,其核心思想是将未排序元素逐个插入到已排序部分的正确位置。以下是两种常见的 Python 实现方式: #### 方法1:交换法(直接插入) ```python def insertion_sort(arr): """插入排序实现(交换法)""" for i in range(1, len(arr)): # 从第二个元素开始遍历 j = i # 将当前元素与前方的有序序列比较并交换 while j > 0 and arr[j] < arr[j-1]: arr[j], arr[j-1] = arr[j-1], arr[j] # 交换相邻元素 j -= 1 return arr # 测试示例 nums = [10, 14, 2, 78, 41, 7, 30, 123, 45, 5] print("排序前:", nums) print("排序后:", insertion_sort(nums.copy())) ``` #### 方法2:移位法(高效实现) ```python def insertion_sort_optimized(arr): """优化版插入排序(移位法)""" for i in range(1, len(arr)): current = arr[i] # 保存当前元素 j = i - 1 # 将大于当前元素的元素后移 while j >= 0 and current < arr[j]: arr[j + 1] = arr[j] # 元素后移 j -= 1 arr[j + 1] = current # 插入到正确位置 return arr # 测试相同示例 print("优化排序后:", insertion_sort_optimized(nums.copy())) ``` #### 算法说明: 1. **时间复杂度**: - 最优情况(已排序):$O(n)$ - 最差/平均情况:$O(n^2)$ 2. **空间复杂度**:$O(1)$(原地排序) 3. **稳定性**:稳定排序(相等元素顺序不变) 4. **核心操作**: - 将数组分为**已排序区**和**未排序区** - 每次取未排序区首元素,在已排序区找到正确位置插入 - 插入过程通过比较和元素后移实现 #### 执行过程示例(以[10, 14, 2]为例): ``` 初始: [10, 14, 2] 第1轮: [10, 14, 2] (14>10, 不移动) 第2轮: [10, 14, 2] → 比较14和2 → [10, 2, 14] → 比较10和2 → [2, 10, 14] ``` #### 算法特点: - 对小规模数据效率高 - 适合近乎有序的数据集 - 实现简单,常数项小 - 是高级算法(如TimSort)的基础组件 ```python # 性能测试(比较两种实现) import time import random test_data = random.sample(range(1, 10000), 5000) start = time.time() insertion_sort(test_data.copy()) print(f"交换法耗时: {time.time() - start:.4f}秒") start = time.time() insertion_sort_optimized(test_data.copy()) print(f"移位法耗时: {time.time() - start:.4f}秒") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值