matlab-归拼排序算法可视化
Posted yangyiqin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了matlab-归拼排序算法可视化相关的知识,希望对你有一定的参考价值。
matlab-归拼排序算法可视化
- 归拼算法第一步,实现合拼两个有序序列
%归拼排序
% 合并的方法就是分别从两个有序序列中拿出一个数来进行比较,小的那一个放到新序列中,
% 然后,从这个小的数所属的序列中拿出一个数来继续比较
% 注意到这两个序列是要有序的
%
归并排序,利用了合并有序序列的思想,把一个序列分成A,B两个序列,
如果这两个序列是有序的,直接合并他们,
但是A,B两个序列未必是有序的,就拿A序列来说,把A序列再分一次,
分成A1,A2,如果A1,A2有序,直接对他们进行合并,A变有序了,
但是A1,A2未必有序啊,继续分,直到分出来的序列里只有一个元素的时候,
一个元素,就是一个有序的序列啊,就可以合并了
这样一层一层的分组,分到最后,一个组里只有一个元素,终于符合合并的条件了,
再一层一层的向上合并
%
%归拼排序,有两个需要关键点,如何拆分与如何合拼
%matlab 或许可以使用 num2cell()但是会使代码迁移性变弱
%实现合拼,可以将代码转为函数形式,便于调用
%
对于两个任意两个 有序序列
测试数据
% list_2=[1 5 10 20];
% list_3=[2 4 6 8 10 14 20 20 45];
%
clear
%测试数据
list_3=[3,3,5,6,9];
list_2=[3,7,8,10,11,13];
n1 = length(list_2); %两个序列的长度
n2 = length(list_3);
N=n1+n2;
list_new=zeros(1,N); %预分配空间,优化过程
na=1; %list_2的索引
nb=1; %list_3的索引,或者说是下标
for k=1:N %这里其实用while也行,只要注意跳出循环就行
%增加判断,如果其中一个数组的元素已经全部在新数组中,只对另一个操作
if na>n1
list_new(k)=list_3(nb);
nb=nb+1;
continue
end
%同上
if nb>n2
list_new(k)=list_2(na);
na=na+1;
continue
end
%
if list_2(na)<list_3(nb)
list_new(k)=list_2(na); %将较小值写入list_new中
na =na+1;
else
list_new(k)=list_3(nb);
nb=nb+1;
end
end
%合拼最后一个数
% if list_2(end)>list_3(end)
% list_new(end)=list_2(end);
% else
% list_new(end)=list_3(end);
% end
list_new
2.合拼两个有序序列函数
%归拼,合拼有序数组
function list_new = list_messagge_sort(my_list,my_list_1)
%判断,只输入一个数组 与输入两个数组的操作是不同的
switch nargin
case 1
N=length(my_list);
N_half =round(N/2);
my_list_2=my_list(1:N_half);
my_list_3=my_list(N_half+1:end);
n1 = length(my_list_2); %两个序列的长度
n2 = length(my_list_3);
case 2
my_list_2=my_list;
my_list_3=my_list_1;
n1 = length(my_list_2); %两个序列的长度
n2 = length(my_list_3);
end
N=n1+n2;
%如果只输入一个数组,且该输入的数组有一个元素,不必要继续
if N<2
list_new=my_list_2;
return
end
list_new=zeros(1,N); %预分配空间,优化过程
na=1; %list_2的索引初值
nb=1; %list_3的索引初值,或者说是下标
%主体程序,迭代中合拼
for k=1:N %这里其实用while也行,只要注意跳出循环就行
%增加判断,如果其中一个数组的元素已经全部在新数组中,只对另一个操作
if na>n1
list_new(k)=my_list_3(nb);
nb=nb+1;
continue
end
%同上
if nb>n2
list_new(k)=my_list_2(na);
na=na+1;
continue
end
%%%%%
if my_list_2(na)<my_list_3(nb)
list_new(k)=my_list_2(na); %将较小值写入list_new中
na =na+1;
else
list_new(k)=my_list_3(nb);
nb=nb+1;
end
end
3 .主体
%归拼排序 调用合拼函数
%本代码采用迭代方法,也可以用递归方法
%合拼在 list_messagge_sort.m函数体中
clear ,close all
list_1=[randperm(30),randperm(20)-20]; %序列(或者说数组)
N = length(list_1); %序列长度
bin_list_length=dec2bin(N); %将N实现十进制与二进制转化,有大用
tem_len=2; %第一轮迭代中使用
n= floor(N/2); %向小取整,如 1.9—— 1, -3.3—— -4,这里用其他语言
bar(list_1); %画原始数据图(用其他语言可以忽略,或另寻可视化方法)
% pause %暂停,观察原始数据图像,按空格键继续
%程序主体
%第一轮,进行2的某次方有关的数据排序
while n>0
for k=1:n
left_pt=(k-1)*tem_len+1;
right_pt= k*tem_len;
tem_list=list_messagge_sort(list_1(left_pt:right_pt));
list_1(left_pt:right_pt)=tem_list; %这里可以简化,tem_list非必要
end
n= floor(n/2);
tem_len=tem_len*2;
%画图
drawnow
pause(.4) %暂停0.4秒,不然图像变化太快
bar(list_1)
end
%第一轮的结果与N的二进制数字相关,如果数组的长度为2的n次方,
%那么第二轮其实不用了;但是比较符合2的n次方长度的数组毕竟是少数,要考虑普适性
nn = length(bin_list_length); %nn为N的二进制数字的长度,用于迭代
tem_n=nn-1; %二进制数字的长度减一,用于迭代中,辅助数据的输入与更新
L =2^tem_n; %同上,初始为序列(数组)中第一个有序序列的长度,也是暂时最大的
% 第二轮,迭代
for ii=2:nn
% 如果数组的某2的n次方的分组数据为空,跳过
if bin_list_length(ii)==\'0\'
tem_n=tem_n-1;
continue
end
if bin_list_length(ii)==\'1\'
tem_n=tem_n-1;
L2=2^tem_n;
tem_list=list_messagge_sort(list_1(1:L), list_1(L+1:L+L2));
list_1(1:L+L2)=tem_list; %同理,这里也可以简化
L=L+2^tem_n;
end
%继续画图
drawnow
pause(.4) %暂停0.4秒,不然图像变化太快,看不清,数据量大时可以不要
bar(list_1)
end
% list_1
以上是关于matlab-归拼排序算法可视化的主要内容,如果未能解决你的问题,请参考以下文章
MATLAB可视化实战系列(二十八)-贪心算法求快速平方根倒数算法中的“魔术数字”含matlab源代码