您的位置:首页 > 编程语言 > MATLAB

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

2017-08-01 10:49 1416 查看
最近在学习排序算法的一些知识。还是比较有趣的。所以好好研究了一下各个算法。并且使用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


算法时间复杂度分析

从上面的代码可以看出来,外层循环也就是趟数最多为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=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


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

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个元素来说,其需要比较的次数为 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-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


算法时间复杂度分析

第一趟,需要比较 N−1 次,第二趟需要比较 N−2 次,⋯,第 N−1 次需要比较1次就可以了。因此总的比较次数

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

今天就先学些到这,后续继续学习补充,希望大神路过指点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐