数据结构与算法——数列排序【冒泡排序、选择排序】

 如有错误,请指正,蟹蟹。 

一、冒泡排序

“如果是大数往下沉的冒泡,就是从左开始;如果是小数往上浮的冒泡,就是从右开始”。

  • 从右往左: 最小值被移到了最左边。 【冒泡法】的本意
  • 从左往右: 最大值被移到了最右边。 此时其实应该叫 【沉石法】
  • 最坏时间复杂度:O(n^2)
    最优时间复杂度:O(n^2)
    平均时间复杂度:O(n^2)
    最坏空间复杂度: 总共 O(n),需要辅助空间 O(1)

从左往右还是从右往左好像都差不多吧,这里是从小到大排序,从右往左,两两比较,右边小的则交换位置,将小的放左边,经过一轮就可以得出一个左边的最小值,在之后的排序中不再参与比较。

数据结构与算法——数列排序【冒泡排序、选择排序】_第1张图片

最小的已经在左边了,继续从最右边开始重复比较,第二次排序不用再比较第一个值,因为已经是上一轮最小了,以此类推,每循环排序一次,需要排序的值就少一个

n=len(arr)
for i in range(n):
    for j in range(n-1,i,-1):
         if arr[j-1]>arr[j]:
            arr[j],arr[j-1]=arr[j-1],arr[j]

数据结构与算法——数列排序【冒泡排序、选择排序】_第2张图片

从左往右两两比较,则和上面的内外循环相反,外循环是右边往左边的i,内循环是左边往右边的j

n=len(arr)
for i in range(n-1,0,-1):
    for j in range(1,i+1):
        if arr[j-1]>arr[j]:
            arr[j],arr[j-1]=arr[j-1],arr[j]

c语言版:源码来自《C语言从入门到精通》

需要注意的是,在交换两个数值时的先后顺序

#冒泡法排序指的是在排序时,每次比较数组中相邻的两个数组元素的值,将较小的数(从小到大排列)排在较大的数前面。
#include
int main()
{
int i,j;
int a[10];
int iTemp;
printf("为数组元素赋值:\n");

for(i=0;i<10;i++)
{
    printf("a[%d]=",i);
    scanf("%d",&a[i]);
}

for(i=1;i<10;i++)
{
    for(i=9;j>=i;j--)
    {
        if(a[j]

二、选择排序

线性搜索数列并找到最小值。将最小值替换为列中左端的数字并进行排序。如果最小值已经在左端,则不执行任何操作。重复相同操作,直到所有数字都被排序。

选择法排序指每次选择所要排序的数组中的最大值(这里指由大到小排序,由
小到大排序则应选择最小值)的数组元素,将这个数组元素的值与最前面没有进行
排序的数组元素的值互换。——《C语言从入门到精通》

数据结构与算法——数列排序【冒泡排序、选择排序】_第3张图片

1、定义变量
1)int i,j;
定义两个变量i和j,i用来做外层循环,j用来做内层循环。
外层循环:循环对比值,如上的每一行,一行更换一个对比值i。
内层循环:查找剩余的值的最小值。
2)int a[10];
定义数组a长度为10
3)int iTemp;
当前值,包含外循环和内循环的当前值。
4)int iPos;
定义iPos为当前值的地址。
2、键盘输入,为数组赋值
for(i=0;i<10;i++)
{
printf("a[%d]=",i)
scanf("%d",&a[i])
}
# 下标从0-9,刚好长度10,a[%d]是值,&a[i]输入的值是指定地址
3、外层循环
#第一次循环i为9,第二次循环i为6,以此类推。
for(i=0;i<9;i++)    # 外循环是从第一个值开始到倒数第二个值,因为最后一个值后面没有值了,也没有值能和它对比了,所以i不包括最后一个--下标为9,所以i是0-8,长度为9。
{
iTemp=a[i];    # 将a[i]设为外循环的当前值,iPos为地址下标。
iPos=i;
for(j=j+1;j<10;j++)    # 内循环j是从i的下一个剩余值开始循环的,j是包括最后一个值的,因为最后一个值也需要进行最小值的比较。
{
# 判断剩余的值中的最小值。a[j]为iTemp当前值,用来做对比值,其右边剩余的值为被对比值,找出最小值,将其更新赋给iTemp。
if(a[j] {
iTemp=a[j];    
iPos=j;
}
}
# 两个值--交换位置,更新赋值。
# 将a[i]的值赋值给a[iPos],将iTemp的值赋值给a[i]。顺序不能反过来,不然a[i]的值被iTemp替换了,就无法知道它的值是多少,就无法赋值给a[iPos]。
a[iPos]=a[i];    
a[i]=iTemp;
}

外循环:(如上每一行的)a[i]为iTemp,和右边剩余的值中的最小值互换位置(内循环判断最小值),如果没有比它小的则不用换,进行下一个循环。
内循环:如果当前值iTemp小于剩下的某个值,则当前值iTemp依旧是当前值iTemp并继续和下一个值对比,
如果剩下的某个值小于当前值,则该某个值就重新设为当前值iTemp,循环,新的当前值iTemp继续和其下一个值进行比较大小。

iPos默认是先从i开始为0,在对比过程中,知道下标j=4为最小值,故ipos=j=4,交换的时候把下标0的值赋值更新给下标为4的;iTemp为a[j]的值2,赋值更新给a[i],使得a[i]为2。

#输出数组
for(i=0;i<10;i++)
{
printf("%d\t",a[i])
}

源码来自《C语言从入门到精通》

#include
int main()
{
int i,j;
int a[10];
int iTemp;
int iPos;
printf("为数组元素赋值:\n");
for(i=0;i<10;i++)
{
    printf("a[%d]=",i);
    scanf("%d",&a[i]);
}

for(i=0;i<9;i++)    
{
    iTemp=a[i]; 
    iPos=i;
    for(j=j+1;j<10;j++)    
        {
            if(a[j]

python版:

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

空间复杂度:O(1)

def selection_sort(arr):
    n = len(arr)
    for i in range(n - 1):
        # 将起始元素设为最小元素
        min_index = i
        for j in range(i + 1, n):    # 从左往右,找出最小值放在左侧,已经放在左侧的将不再对比
            if arr[j] < arr[min_index]:
                min_index = j    # 当前值小于上面的最小值,则将当前值重新赋值给最小值min_index
        arr[min_index], arr[i] = arr[i], arr[min_index]    # 交换位置
array = [26, 11, 99 , 33, 69, 77, 55, 56, 67]
print("原列表:")
print(array)
selection_sort(array)
print("排序后的列表:")
print(array)

你可能感兴趣的:(数据结构,排序算法,算法)