1. 程式人生 > >Matlab實現二次取中法求第K小

Matlab實現二次取中法求第K小

%使用二次取中求第K小

%主函式
function main()
    setGlobalx(5);%設定視窗大小
    k=9;%第K小
    arr = [1,5,5,7,2,3,19,19,4,6,89,8];
    fprintf('陣列為:')
    disp(arr)
    fprintf('排序為:')
    disp(sort(arr))
    y=select2(arr,k);%呼叫函式求第K小
    fprintf('二次取中第 %d小為:%d\n', k,y);%列印輸出
end

%讓陣列對temp這個數進行一次快速排序排序(小於它的在它前,大於它的在它後)->返回陣列和它的腳標
%注意matlab中是值傳遞,要想獲得改變的東西,需要把它返回在賦值利用
function [arr,index]=partion(A,temp)
p=length(A);
i=2;
while(true)
    while(true)
        if i<p&&A(i)<=temp
            i=i+1;
        else
            break;
        end
    end
    while(true)
        if A(p)>temp&&p>=0
            p=p-1;
        else
            break;
        end
    end
    if i<p
        v=A(i);
        A(i)=A(p);
        A(p)=v;
    else
        index=p;
        arr=A;
        break;
    end
    
end
end

%利用遞迴求第K小,返回值value即為所求
function value = select2(arr,k)
    if length(arr)<=getGlobalx %不足視窗大小直接排序返回第K個
        arr=sort(arr);
        value=arr(k);
        return;
    end
    M=[];
    for i=1:getGlobalx:(length(arr)-getGlobalx+1)%腳標從1開始,步長為5,直到長度-4
        if (i+5)>length(arr)
            break;
        end
        m=[arr(i),arr(1+i),arr(2+i),arr(3+i),arr(4+i)];
        m=sort(m);%排序取出中間的值
        M=[M,m(3)];
    end
    if mod(floor(length(arr)/getGlobalx),2)==1 %M長度為奇數
         % disp(M);
         % disp(1+floor(floor(length(arr)/getGlobalx)/2));
        v=select2(M,1+floor(floor(length(arr)/getGlobalx)/2));
    else%M長度為偶數
        %disp(M);
          %disp(floor(floor(length(arr)/getGlobalx)/2));
       v=select2(M,floor(floor(length(arr)/getGlobalx)/2));
    end
    [arr,j]=partion(arr,v);%對v進行一次快排,返回陣列和他是第幾個
    %disp(arr);
    if k==j %正好相等就返回v的值就行
        value=v;
        return;
    end
    if k<j %如果j比所求的k大,說明在它前面
            arr1=arr(1:j);
           % disp(arr1);
            value=select2(arr1,k);  %對他前面的陣列求第K小
            return;
    end
    if k>j %同理,說明在它後面
        arr2=arr(j:length(arr)); 
        %disp(j)
       % disp(arr2);
        value=select2(arr2,k-j+1); %對他後面的陣列求第k-j+1小
        return;
    end
    end

%get方法
function setGlobalx(var)
    global x
    x=var;
end

%set方法
function r=getGlobalx
    global x
    r=x;
end