Matlab實現二次取中法求第K小
阿新 • • 發佈:2018-12-14
%使用二次取中求第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