1.最大値と最小値を選択します。a
)最大値または最小値を選択します。配列のすべての要素をトラバースして、線形時間O(n)で完了することができます。
コード:
int findmax(int* A,int N)
{
int max = A[0];
int tmp;
for(int i = 1;i<N;i++){
tmp = A[i];
if(tmp>max){
max = tmp; }
}
return max;
}
b)最大値と最小値を同時に選択します
分析:最大値と最小値を個別に見つけO(2(n-1))
ます。
したがって、時間の複雑さはです。したがって、入力データのペアを比較し、現在の最小値と比較して小さいほど、現在の最大値と比較して大きい。したがって、4つの要素が3回比較され、時間の複雑さはになりO(3[n/2])
ます。
偽のコード:
int findmax(int* A,int N)
{
int max,min;
if(n%2 == 0) {
//n为偶数
if(A[0]>A[1]) {
max =A[0]; min =A[1];}
else {
max =A[1]; min =A[0]; }
}
else{
max =min =A[0];
}
int tmp1,tmp2; //同时比较两个数
。。。
return max, min;
}
2.選択アルゴリズム:リターン配列A [P ... R]におけるi番目の最小の要素
アイデア:分割統治、クイックソートの変更、時間複雑でありO(n)
、
クイックソートと同様に、入力データは依然として再帰的に分割されています。しかし、クイックソートは両側で再帰を続けているため、時間の複雑度はO(nlgn)ですが、選択アルゴリズムは片側でのみ再帰し、時間の複雑度はO(n)です。
コード(要素が異なると想定):
int SelectK(int *A, int l, int r, int k);//找第k小数
{
if(l == r) return A[l];
int pivot = Partition(A, l, r); //返回主元的下标
if(pivot == k-1) return A[pivot]; // 主元的下标为k-1则返回(下标从0开始,所以-1)
else if(pivot >k-1) return SelectK(A, l, pivot-1, k); // 若下标大则在左边递归
else return SelectK(A, pivot+1, r, k-pivor-2); // 小则在右边递归
}
int Partition(int *A, int l, int r)
{
int pivot = A[r]; //将数组最后一个值作为主元
int i = l;
int j = r-1;
for(;;){
while (A[i]<pivot){
i++;}
while (A[j]>pivot){
j--;}
if(i<j) swap(A[i],A[j]);
else break;
}
swap(A[i],A[right]); //将主元放在中间位置
return i;
}
注:配列の最後の値はピボットとして使用され、ピボットが配置されている添え字は要素の数を示すために使用されます。