最近在学习排序算法的一些知识。还是比较有趣的。所以好好研究了一下各个算法。并且使用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-iif a(1,j)>a(1,j+1)temp=a(1,j);a(1,j)=a(1,j+1);a(1,j+1)=temp;endend
end
算法时间复杂度分析
从上面的代码可以看出来,外层循环也就是趟数最多为N−1次,而内层循环比较次数最多为N次,最少为1次,所以平均
次数为
N+12 次,所以总的次数为T(n)=(N−1)×N+12=N2−12次,所以其算法时间复杂 度为O(n2).冒泡改进
有时候碰到的序列里面有大部分是有序,只有少数的无序的,那么有可能就不需要比较那么多趟去实现这个冒泡,因此,可以设置一个旗帜变量exchangeFlag,发生元素交换了,则exchangeFlag=1,否则为0.
那么改进之后的代码为:
exchangeFlag=true;
tic
for i=1:m exchangeFlag=0for j=1:m-iif a(1,j)>a(1,j+1)temp=a(1,j);a(1,j)=a(1,j+1);a(1,j+1)=temp;exchangeFlag=1endendif ~exchangeFlagbreak;end
end
这里就有一个旗帜变量,进行一个统计是否发生了元素交换。这样的当一个序列里面大部分有序,只有少数无序的时候就比较使用,不要去试行N−1趟的比较了。
- Python 实现
for i in range(0,m):exchangeFlag=0for j in range(0,m-i-1):if a[j]>a[j+1]:a[j],a[j+1]=a[j+1],a[j]exchangeFlag=1if ~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:mif 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);elsebreak;endj=j-1;enda(j)=temp;end
end
toc
测试输出结果为:
-1 1 2 3 4 5 6 7 8
算法时间复杂度分析
对于第i个元素来说,其需要比较的次数为
i−1 次,那么对于有N个元素的序列来说,最坏的情况下,其需要的次数为T(n)=1+2+3+⋯+(n−1)=n(n−1)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-1temp=a[i]a[i]=a[i-1]while (j-1)>=0:if temp<a[j-1]:a[j]=a[j-1]else:breakj=j-1a[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:mminValue=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
算法时间复杂度分析
第一趟,需要比较 N−1 次,第二趟需要比较 N−2 次,⋯,第 N−1 次需要比较1次就可以了。因此总的比较次数
为:T(n)=1+2+3+⋯+(n−1)=n(n−1)2,也就是说其算法时间复杂度为 O(n2) 。
今天就先学些到这,后续继续学习补充,希望大神路过指点。