時間複雑度から多O(nlogn)までの配列並べ替えを試みる
6660 ワード
効率的な配列ソートを探るハイブリッドソート方式 一、主な考え方 1、時間複雑度m a x{O(m a x a−m i n a)、O(n)}max{O(maxa−mina)、O(n)}max{O(maxa−mina)、O(n)}のソート法 2、混合ソート方法 二、アルゴリズム適用の場合
ハイブリッドソート方式
一、主な考え方
現在、多くのソートアルゴリズムの中で、最も速いアルゴリズムの時間複雑度はO(n l o g n)O(nlogn)O(nlogn)であり、より効率的なアルゴリズムを実現できるだろうか.本稿では、時間的複雑度がO(n l o g n)O(nlogn)O(nlogn)O(nlogn)までのアルゴリズムを探すが、このアルゴリズムは独自の新しいアルゴリズムではなく、2つの異なるアルゴリズムをその優位性を混合したものであるため、「混合ソートアルゴリズム」と呼ぶ.
1、時間複雑度m a x{O(m a x a−m i n a),O(n)}max{O(maxa−mina),O(n)}max{O(maxa−mina),O(n)}のソート法
まず、特定の状況において優れたアルゴリズムを見る.与えられた配列a r[n]arr[n]arr[n]に対して、配列a r arr arrを遍歴し、a r r arr arrにおける最大値m a x a maxaと最小値m i n a minaを得る. は、m a x a−m i n a+1 maxa−mina+1 maxa−mina+1の大きさの配列s o r t sort sortを割り当て、要素の初期値はいずれも0 0 0に設定する. 配列a r arr arrを2回目に巡回し、現在の配列要素a r[i]arr[i]arr[i]arr[i]に対応するs o r t[a r[i]−m i n a]sort[arr[i]−mina]sort[arr[i]−mina]に1を加える. 配列s o r t sort sortを巡回する、全ての非ゼロ要素s o r t[i]sort[i]sort[i]sort[i]に対応する数m i n a+i mina+i mina+i mina+iを印刷するとともに、s o r t[i]sort[i]sort[i]sort[i]を1 1ずつ減算.s o r t[i]sort[i]sort[i]sort[i]sort[i]がゼロの場合、次の要素が処理する.
対応するC++コードは
通常、m a x−a−m i n a+1>n maxa−mina+1>n maxa−mina+1>nであるが、a r arr arr中のほとんどの元素が同時にm a x−a−m i n a+1現在の他のアルゴリズム(ヒルソートを除く)では、最も速いのはスタックソート、高速ソートと集計ソートであり、時間複雑度はいずれもO(nl o g n)O(nlogn)O(nlogn)、空間複雑度はそれぞれO(1)、O(l o g n)、O(n)O(1)、O(logn)、O(n)O(1)、O(logn)、O(logn)、O(n)である.ヒルソートの最適時間複雑度はまだ証明中であるため、本文はしばらく考慮しない.
m a x a−m i n an l o g n maxa-mina>nlogn maxa-mina>nlognの場合、集計/高速ソートがより好ましい.両者を組み合わせると,O(n l o g n)O(nlogn)O(nlogn)O(nlogn)を常に超えない時間複雑度のアルゴリズムが得られるだろうか.
2、混合ソート方法
以上より、両者の性能を兼ね備えたハイブリッドソートアルゴリズムを試みることができる.
与えられた配列a r[n]arr[n]arr[n]に対して、配列a r arr arrを遍歴し、a r r arr arrにおける最大値m a x a maxaと最小値m i n a minaを得る. m a x a−m i n a maxa−mina−minaとn l o g n nlogn nlognの大きさを比較し、m a x a−m i n an l o g n maxa-mina>nlogn maxa-mina>nlognになると4に移る. n e w S o r t()newSort()newSort()を使用してソートする. は集計/高速/スタックソートアルゴリズムを用いてソートする.
ハイブリッドソートアルゴリズムC++コード(ここではステップ4でクイックソートを例に挙げる)
アルゴリズム時間複雑度m i n{O(n l o g n),m a x{O(m a x a−m i n a),O(n)}min{O(nlogn),max{O(maxa−mina),O(n)}min{O(nlogn),max{O(maxa−mina),O(n)}}}}},空間複雑度O(l o g n)o r O(m a−a−m a−m i n a)O(logn)orO(maxa−mina)O(lognn(lognn)O(lognn)O(lognn(maxa−mina)O(lognn(lognn)O(lognn(lognn)O(maxa−min) or O(maxa-mina).
二、アルゴリズム適用の場合
本アルゴリズムは,m a x a−m i n a maxa−mina−maxa−minaを可能な限り小さいデータセット,すなわち,ある区間にデータ分布が集中するデータセット,e g:{1,5,3,3,2,4}eg:{1,5,3,2,4}eg:{1,5,3,2,4},{1,3,4,3,3,5}{1,3,4,3,3,3,3,3,5}{1,3,3,4,3,3,4,3,3,3,5}{5,3,4,3,3,3,3,3,3,3,3,3,3,5}eg本アルゴリズムの性能は優れている.
Y J Y F e b . 2 0 t h , 2021\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\YJY\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Feb.\20^{th}\,\2021 YJY Feb. 20th , 2021
ハイブリッドソート方式
一、主な考え方
現在、多くのソートアルゴリズムの中で、最も速いアルゴリズムの時間複雑度はO(n l o g n)O(nlogn)O(nlogn)であり、より効率的なアルゴリズムを実現できるだろうか.本稿では、時間的複雑度がO(n l o g n)O(nlogn)O(nlogn)O(nlogn)までのアルゴリズムを探すが、このアルゴリズムは独自の新しいアルゴリズムではなく、2つの異なるアルゴリズムをその優位性を混合したものであるため、「混合ソートアルゴリズム」と呼ぶ.
1、時間複雑度m a x{O(m a x a−m i n a),O(n)}max{O(maxa−mina),O(n)}max{O(maxa−mina),O(n)}のソート法
まず、特定の状況において優れたアルゴリズムを見る.与えられた配列a r[n]arr[n]arr[n]に対して、
対応するC++コードは
vector newSort(vector &arr){
// 1
int mina = arr[0], maxa = arr[0];
for(int i : arr) {
mina = mina > i ? i : mina;
maxa = maxa < i ? i : maxa;
}
// 2,3
vector sort(maxa - mina + 1);
for(int i : arr)
sort[i - mina]++;
// 4
vector res(arr.size());
int index = 0;
for(int i = 0; i < maxa - mina + 1; i++){
if(sort[i]) {
res[index++] = mina + i;
sort[i--]--;
}
}
return res;
}
通常、m a x−a−m i n a+1>n maxa−mina+1>n maxa−mina+1>nであるが、a r arr arr中のほとんどの元素が同時にm a x−a−m i n a+1
m a x a−m i n a
2、混合ソート方法
以上より、両者の性能を兼ね備えたハイブリッドソートアルゴリズムを試みることができる.
与えられた配列a r[n]arr[n]arr[n]に対して、
ハイブリッドソートアルゴリズムC++コード(ここではステップ4でクイックソートを例に挙げる)
// newSort()
vector newSort(vector &arr, int mina, int maxa){
vector sort(maxa - mina + 1);
for(int i : arr)
sort[i - mina]++;
vector res(arr.size());
int index = 0;
for(int i = 0; i < maxa - mina + 1; i++){
if(sort[i]) {
res[index++] = mina + i;
sort[i--]--;
}
}
return res;
}
//
// part(), , , p, p
int part(vector &arr, int low, int high){
int p = arr[low];
while(low < high) {
while(low < high && arr[high] >= p) high--;
arr[low] = arr[high];
while(low < high && arr[low] <= p) low++;
arr[high] = arr[low];
}
arr[low] = p;
return low;
}
vector quickSort(vector &arr, int low, int high){
if(low < high) {
int pos = part(arr, low, high);//
quickSort(arr, low, pos - 1);
quickSort(arr, pos + 1, high);
}
return arr;
}
//
vector mixSort(vector &arr){
// 1
int mina = arr[0], maxa = arr[0];
int n = arr.size();
for(int i : arr) {
mina = mina > i ? i : mina;
maxa = maxa < i ? i : maxa;
}
// 2,3,4, log 2 ;
if(maxa - mina + 1 < n * log(n) / log(2)) return newSort(arr, mina, maxa);
return quickSort(arr, 0, n - 1);//
}
//
int main(){
vector a = {6, 9, 4, 2, 8, 6, 7, 3, 2, 5, 1};
a = mixSort(a);
for(int i : a) cout << i << ' ';
return 0;
}
アルゴリズム時間複雑度m i n{O(n l o g n),m a x{O(m a x a−m i n a),O(n)}min{O(nlogn),max{O(maxa−mina),O(n)}min{O(nlogn),max{O(maxa−mina),O(n)}}}}},空間複雑度O(l o g n)o r O(m a−a−m a−m i n a)O(logn)orO(maxa−mina)O(lognn(lognn)O(lognn)O(lognn(maxa−mina)O(lognn(lognn)O(lognn(lognn)O(maxa−min) or O(maxa-mina).
二、アルゴリズム適用の場合
本アルゴリズムは,m a x a−m i n a maxa−mina−maxa−minaを可能な限り小さいデータセット,すなわち,ある区間にデータ分布が集中するデータセット,e g:{1,5,3,3,2,4}eg:{1,5,3,2,4}eg:{1,5,3,2,4},{1,3,4,3,3,5}{1,3,4,3,3,3,3,3,5}{1,3,3,4,3,3,4,3,3,3,5}{5,3,4,3,3,3,3,3,3,3,3,3,3,5}eg本アルゴリズムの性能は優れている.
Y J Y F e b . 2 0 t h , 2021\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\YJY\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\Feb.\20^{th}\,\2021 YJY Feb. 20th , 2021