排序算法一:冒泡排序,插入排序以及选择排序原理与MATLAB实现

最近在学习排序算法的一些知识。还是比较有趣的。所以好好研究了一下各个算法。并且使用matlab进行了个基本的实现,目前仅仅是实现吧,优化什么的可能目前的水平达不到吧,毕竟是用matlab实现,还是比较简单。以后还是希望使用C/C++,或者python来实现一下。先本着学习算法思想的原则,用matlab搞一搞吧。

冒泡排序

  • 冒泡排序 思想

    这个方法就是在每一趟的循环中依次比较前后两个元素之间的大小,然后进行一个交换。这样在多趟循环中实现无序数列的有序排列。下面是使用matlab实现的

clc
clear 
close

% aa=round(rand(1,100000)*500000000) ;%产生随机数组
% a=aa;
a=[0 6,5,3,1,8,7,2,4];
N=size(a,2);
for i=1:N 
    for j=1:N-i
        if a(1,j)>a(1,j+1)
            temp=a(1,j);
            a(1,j)=a(1,j+1);
            a(1,j+1)=temp;
        end
    end
end
  • 算法时间复杂度分析

    从上面的代码可以看出来,外层循环也就是趟数最多为 N1 次,而内层循环比较次数最多为 N 次,最少为1次,所以平均

    次数为N+12次,所以总的次数为 T(n)=(N1)×N+12=N212 次,所以其算法时间复杂 度为 O(n2) .

  • 冒泡改进
    有时候碰到的序列里面有大部分是有序,只有少数的无序的,那么有可能就不需要比较那么多趟去实现这个冒泡,因此,可以设置一个旗帜变量exchangeFlag,发生元素交换了,则exchangeFlag=1,否则为0.
    那么改进之后的代码为:

exchangeFlag=true;
tic
for i=1:m 
    exchangeFlag=0
    for j=1:m-i
        if a(1,j)>a(1,j+1)
            temp=a(1,j);
            a(1,j)=a(1,j+1);
            a(1,j+1)=temp;
            exchangeFlag=1
        end
    end
    if ~exchangeFlag
        break;
    end 
end

这里就有一个旗帜变量,进行一个统计是否发生了元素交换。这样的当一个序列里面大部分有序,只有少数无序的时候就比较使用,不要去试行 N1 趟的比较了。

  • Python 实现
for i in range(0,m):
    exchangeFlag=0
    for j in range(0,m-i-1):
        if a[j]>a[j+1]:
            a[j],a[j+1]=a[j+1],a[j]
            exchangeFlag=1
    if ~exchangeFlag:
        break
print(a)

插入排序

  • 插入排序的思想

    插入排序是在一个已经有序的小序列的基础上,一次插入一个元素。当然,刚开始这个有序的小序列只有1个元素,就是第一个元素。比较是从有序序列的末尾开始,也就是想要插入的元素和已经有序的最大者开始比起,如果比它大则直接插入在其后面,否则一直往前找直到找到它该插入的位置。如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

  • matlab代码

clc
clear
close all
a=[6 5 3 1 8 7 2 4 -1];
m=size(a,2);
tic
for i=2:m
    if a(1,i)<a(1,i-1)
        j=i-1; %记录这个位置
        temp=a(i); %将这个位置的元素值取出来
        a(i)=a(i-1); %将大的元素后移
        while (j-1)>0 %这里实现待插入的元素和已排好序列进行比较
            if temp<a(j-1)
                a(j)=a(j-1);
            else
                break;
            end
            j=j-1;
        end
        a(j)=temp;
    end
end
toc

测试输出结果为:

    -1     1     2     3     4     5     6     7     8
  • 算法时间复杂度分析

    对于第 i 个元素来说,其需要比较的次数为 i1 次,那么对于有 N 个元素的序列来说,最坏的情况下,其需要的次数为

    T(n)=1+2+3++(n1)=n(n1)2,也就是说其算法时间复杂度为 O(n2)

  • python实现

a=[6,5,3,1,8,7,2,4]
m=a.__len__()
for i in range(1,m):
    if a[i]<a[i-1]:
        j=i-1
        temp=a[i]
        a[i]=a[i-1]
        while (j-1)>=0:
            if temp<a[j-1]:
                a[j]=a[j-1]
            else:
                break
            j=j-1
        a[j]=temp
print(a)

简单选择排序

  • 简单选择排序思想

    在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。

  • matlab代码实现

a=[6 5 3 1 8 7 2 4];
m=size(a,2);
for i=1:m
    minValue=min(a(1,i:end)); %找到剩余序列的最大值
    minValueIndex=find(a(1,i:end)==min(a(1,i:end)))+i-1; %找到剩余序列最大值所在原序列中的索引值
    a(1,minValueIndex)=a(i); %交换
    a(i)=minValue;
end
  • 算法时间复杂度分析

    第一趟,需要比较 N1 次,第二趟需要比较 N2 次, ,第 N1 次需要比较1次就可以了。因此总的比较次数

    为: T(n)=1+2+3++(n1)=n(n1)2 ,也就是说其算法时间复杂度为 O(n2)

今天就先学些到这,后续继续学习补充,希望大神路过指点。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值