高级数据结构与算法(二):各种排序算法:插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序及matlab实现

1.插入排序

1.从第一个元素开始,该元素可以认为已经被排序

eq?While%5Cquad%20%5Ctextbf%7Bsuccess%7D
2.取下一个元素tem,从已排序的元素序列从后往前扫描
3.如果该元素大于tem,则将该元素移到下一位
4.重复步骤3,直到找到已排序元素中小于等于tem的元素
5.tem插入到该元素的后面,如果已排序所有元素都大于tem,则将tem插入到下标为0的位置

eq?end

clc;clear;
rng(0)
a=randi([1,100],1,40);
c=a;
for i=2:length(a)
    b=a(i);
    j=i-1;
    while(j>=1)
        if(a(j)>b)
            a(j+1)=a(j);
            a(j)=b;
        elseif(a(j)<b)
            a(j+1)=b;
            break;
        end
        j=j-1;
    end
end
sort(c)

2. 希尔排序

1.先选定一个小于N的整数gap作为第一增量,然后将所有距离为gap的元素分在同一组,并对每一组的元素进行直接插入排序。然后再取一个比第一增量小的整数作为第二增量,重复上述操作…
2.当增量的大小减到1时,就相当于整个序列被分到一组,进行一次直接插入排序,排序完成。

function a=charu(a)
for i=2:length(a)
    b=a(i);
    j=i-1;
    while(j>=1)
        if(a(j)>b)
            a(j+1)=a(j);
            a(j)=b;
        elseif(a(j)<b)
            a(j+1)=b;
            break;
        end
        j=j-1;
    end
end
end
gap=4;
b=floor(length(a)/gap);
while(b~=0)
    for i=1:b
        a(i:b:(floor(length(a)/b)-1)*b+i)=charu(a(i:b:(floor(length(a)/b)-1)*b+i));
    end
    if(b/gap<1)
        b=round(b/gap);
    else
        b=floor(b/gap);
    end
end

3.选择排序

每次从待排序列中选出一个最小值,然后放在序列的起始位置,直到全部待排数据排完即可。
实际上,我们可以一趟选出两个值,一个最大值一个最小值,然后将其放在序列开头和末尾,这样可以使选择排序的效率快一倍。

clc;clear;
a=randi([1,100],1,40);
c=a;
d=sort(c);
% for i=1:length(a)
%     b=a(i);
%     for j=i:length(a)
%         if(a(j)<b)
%             b=a(j);
%             k=j;
%         end
%     end
%     a(k)=a(i);
%     a(i)=b;
% end
for i=1:round(length(a)/2)
    b=a(i);
    f=a(length(a)-i+1);
    for j=i:length(a)-i+1
        if(a(j)<b)
            b=a(j);
            k=j;
        elseif(a(j)>f)
            f=a(j);
            l=j;            
        end
    end
    a(k)=a(i);
    a(i)=b;
    a(l)=a(length(a)-i+1);
    a(length(a)-i+1)=f;
end    
        

4.冒泡排序

左边大于右边交换一趟排下来最大的在右边

clc;clear;
a=randi([1,100],1,40);
c=a;
d=sort(c);
n=length(a);
while(n~=1)
    for i=1:n-1
       if(a(i+1)<a(i))
          b=a(i);
          a(i)=a(i+1);
          a(i+1)=b;
       end
    end
    n=n-1;
end

5.堆排序

向下调整算法-前提:当前树的左右子树必须都是一个小堆
向下调整算法的核心思想:选出左右孩子中小的哪一个,跟父亲交换,小的往上浮,大的往下沉,如果要建大堆则相反

clc;clear;
A=randi([1,100],1,39);
[C,index]=sort(A);
a=erchashu(A);
k=0;

while(k~=length(a)-2)
    k=0;
    for i=1:floor((length(A)-1)/2)
        if(a(i,2:3)~=0)
            b=a(i,1);
            c=min(A(a(i,:)));
            if(c~=A(a(i,1)))
                if(c==A(a(i,2)))
                    a(find(a(:,1)==a(i,2)),1)=b;
                    a(i,1)=a(i,2);
                    a(i,2)=a(2*i,1);
                else
                    a(find(a(:,1)==a(i,3)),1)=b;
                    a(i,1)=a(i,3);
                    a(i,3)=a(2*i+1,1);
                end
            end
        end

            

        
%         if(mod(length(A),2)==0)
%             a(floor((length(A)-1)/2)+1,2)=length(A);
%             a(floor((length(A)-1)/2)+1,3)=0;
%         end
%         a(floor((length(A)-1)/2)+2:length(A),2)=0;
%         a(floor((length(A)-1)/2)+2:length(A),3)=0;
        
    end
    for i=1:length(a)-1
        if(A(a(i,1))<=A(a(i+1,1)))
            k=k+1;
        end
    end
end
% 
%                 
% 
% 
% 
% 




% while(k~=length(a))
%     k=0;
%     for i=1:length(a)
%         b=a{i}.value;
%         c=min([A(a{i}.value),A(a{i}.left),A(a{i}.right)]);
%         if(c~=A(a{i}.value))
%             if(c==A(a{i}.left))
%                 a{i}.value=a{i}.left;
%                 a{i}.left=b;
%                 a{2*i}
%             else
%                 a{i}.value=a{i}.left;
%                 a{i}.right=b;
%             end
%         end
%     end
%     for i=1:length(a)
%         c=min([A(a{i}.value),A(a{i}.left),A(a{i}.right)]);
%         if(c==A(a{i}.value))
%             k=k+1;
%         end
%     end
% end
        
                
                




    




    
    
    
    

% a{1}(:,1)=[A(1);A(1)];
% a{1}(:,2)=[A(2);A(3)];
% for i=2:floor(log2(length(A)+1))
% %     if(i==floor(log2(length(A)+1))+1)
% %         a{i}=A(2^(i-1):end)';
% %         break;
% %     end
%     a{i}(1:2:2^(i)-1,1)=A(2^(i-1):2^(i)-1)';
%     a{i}(2:2:2^(i),1)=A(2^(i-1):2^(i)-1)';
%     if(i==floor(log2(length(A)+1)))
%         a{i}(1:length(A)-2^(i)+1,2)=A(2^(i):end)';
%         continue;
%     end
% 
%     a{i}(:,2)=A(2^(i):2^(i+1)-1)';
% end
% for i=1:floor(log2(length(A)+1))
%     for j=1:2:length(a{i}(:,1))-1
%         b=a{i}(j,1);
%         s=[a{i}(j,1),a{i}(j,2),a{i}(j+1,2)];
%         c=min(s);
%         if(c~=a{i}(j,1))
%                 if(c==a{i}(j,2))
%                     a{i}(j,2)=b;
%                     if(i~=floor(log2(length(A)+1)))
%                         a{i+1}(2*j-1:2*j,1)=b;
%                     end
%                 else
%                     a{i}(j+1,2)=b;
%                     if(i~=floor(log2(length(A)+1)))
%                         a{i+1}(2*j+1:2*j+2,1)=b;
%                     end
%                 end
%         end
%         a{i}(j:j+1,1)=c;
%     end
% end
function a=erchashu(A)
% a{1}=struct('value', 1, 'left', 2, 'right', 3,'parent',[]);
% for i=2:length(A)
%     a{i}=struct('value', i, 'left', 2*i, 'right', 2*i+1,'parent',floor(i/2));
%     if(i>floor((length(A)-1)/2))
%         a{i}=struct('value', i, 'left', [], 'right', [],'parent',floor(i/2));
%     end 
% 
% end
% if(mod(length(A),2)==0)
%     a{floor((length(A)-1)/2)+1}=struct('value', floor((length(A)-1)/2)+1, 'left',length(A) , 'right', [],'parent',floor((floor((length(A)-1)/2)+1)/2));
% end
a(:,1)=(1:length(A))';
for i=1:floor((length(A)-1)/2)
    a(i,2)=2*i;
    a(i,3)=2*i+1;
end
if(mod(length(A),2)==0)
    a(floor((length(A)-1)/2)+1,2)=length(A);
    a(floor((length(A)-1)/2)+1,3)=0;
end
a(floor((length(A)-1)/2)+2:length(A),2)=0;
a(floor((length(A)-1)/2)+2:length(A),3)=0;
end
            
                
        

6.快速排序

1、选出一个key,一般是最左边或是最右边的。
2、定义一个begin和一个end,begin从左向右走,end从右向左走。(需要注意的是:若选择最左边的数据作为key,则需要end先走;若选择最右边的数据作为key,则需要bengin先走)。
3、在走的过程中,若end遇到小于key的数,则停下,begin开始走,直到begin遇到一个大于key的数时,将begin和right的内容交换,end再次开始走,如此进行下去,直到begin和end最终相遇,此时将相遇点的内容与key交换即可。(选取最左边的值作为key)
4.此时key的左边都是小于key的数

,key的右边都是大于key的数
5.将key的左序列和右序列再次进行这种单趟排序,如此反复操作下去,直到左右序列只有一个数据,或是左右序列不存在时,便停止操作,此时此部分已有序

function c=begend(l,begin,en)

if(begin>=en)
    return ;
end
key=begin;
m=begin;
n=en;
c=l;
while(begin<en)
    while(c(en)>=c(key)&&begin<en)
        en=en-1;
    end
    while(c(begin)<=c(key)&&begin<en)
        begin=begin+1;
    end
    s=c(begin);
    c(begin)=c(en);
    c(en)=s;
end
s=c(key);
c(key)=c(en);
c(en)=s;
key=en;
l=c;
begend(l,m,key-1);
begend(l,key+1,n);
end
clc;clear;
A=randi([1,100],1,39);
c=begend(A,1,39);
% [C,index]=sort(A);
% [a,n]=begend(A);
% s=fengei(a,n);
% k=max([length(a(1:n(1)-1)),length(a(n(1)+1:end))]);
% % while(k==1)
% for i=1:length(s)
%     [d{i},l{i}]=begend(s{i});
% end

 
 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

从零开始的奋豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值