包括,選擇最大值,最小值,選擇第k大元素的演算法。其中選擇第k大元素包括隨機選擇演算法和最壞線性時間演算法。選擇演算法有乙個假設就是輸入的元素都不相同,如果是輸入序列有重複的,那麼這些演算法都不適用。由於輸入序列條件苛刻,因此實際應用中感覺很難用,還不如老老實實先排序,然後再遍歷尋找。
下面是演算法實現**:
public class mysearchs
else
while (thestart + 1 < a.length)
if (a[thestart + 1] < minv)
}else
if (a[thestart] < minv)
}thestart += 2;}}
#region 隨機選擇演算法
/// /// 隨機選擇演算法:分割槽採用隨機快排分割槽方法。尋找第i大元素.
/// 演算法依賴:輸入陣列元素無重複.
///
/// 輸入陣列
/// 陣列開始索引
/// 陣列結束索引
/// 第i大元素
/// 第i大元素值
public static int randomizeselect(int a, int p, int r, int i)
if (p > r)
int q = randomizepartion(a, p, r);
int k =q - p + 1;
if (i == k)
else if (i < k)
else
}/// /// 隨機分割槽演算法
///
/// 輸入陣列
/// 陣列開始位置
/// 陣列結束位置
/// 分割槽位置
private static int randomizepartion(int a, int s, int e)
/// /// 分割槽演算法:和快排分割槽演算法一樣
///
/// 要分割槽的陣列
/// 要分割槽陣列起始位置
/// 要分割槽陣列結束位置
/// 分割槽索引
private static int partion(int a, int s, int e)
}swapvalue(a, i + 1, e);
return (i + 1);
}#endregion
private static void swapvalue(int a, int i, int j)
#region 分組選擇演算法
/// /// 分組元素數目
///
private const int groupnum = 5;
/// /// 分組組內中位索引.
///
private const int groupmid = 3;
/// /// 選擇分割槽演算法,這裡採用的分割槽主元素是傳入的引數.
///
/// 待分割槽陣列
/// 待分割槽陣列起始位置
/// 待分割槽陣列結束位置
/// 主元素值
/// 分割槽索引
private static int selectpartion(int a, int p, int r, int x)
//如果i!=j則交換i,j的值.
if (i != j)}}
return i - 1;
}/// /// 選擇第k大元素,採用分組中位之中位數為分割槽主元素方法.
/// 演算法依賴:輸入陣列元素無重複.
///
/// 輸入陣列
/// 輸入陣列起始位置
/// 輸入陣列結束位置
/// 第k大元素
/// 第k大元素
public static int selectbygroup(int a, int p, int r, int k)
else
}//當前處理的子陣列元素個數
int theelementnum = r - p + 1;
//組數,注意這裡的除法是整除,採用的截斷尾數方式.
int thegroups = theelementnum / groupnum;//組數,如果不是整除,最後一組忽略.
//對每組進行插入排序,取每組的中位數,並交換到從p開始的位置
//處理完成後從p開始的thgroups個元素就是前面每組的中位數.
for (int i = 0; i < thegroups; i++)
//中位序號,後面的演算法將選擇前面分組得來的中位數裡的中位數.
int thegroupmid = thegroups / 2;
if (thegroups % 2 != 0)
//選擇分組得來的中位數的中位數,將作為分割槽的主元素.
int x = selectbygroup(a, p, p + thegroups - 1, thegroupmid);
//以分組中位數的中位數作為主元素來分割槽.
int theindex = selectpartion(a,p, r, x);
int j = theindex - p + 1;
//如果k<=j則第k大元素在低分割槽,否則,在高分割槽.注意在高分割槽,則第k大需變成尋找第k-j大,
//這是跟隨機選擇演算法乙個非常不同的地方.
if (k <= j)
return selectbygroup(a, p, theindex, k);
else
return selectbygroup(a, theindex + 1, r, k - j);
}/// /// 插入排序
///
/// 需排序的陣列
/// 需排序的陣列開始元素位置
/// 需排序的陣列結束元素位置
private static void insertsort(int a, int s, int e)
a[j + 1] = thecurrval;}}
#endregion
}
後記:上述線性期望的選擇演算法是否可以改造成可適用有重複元素的情況,我感覺是比較困難,採用先排序再處理,增加的也是線性時間,只要排序演算法是線性的,也可以達到線性選擇。其實比較好的做法就是資料開始就是排序的,每次刪除和增加都保持排序,雖然慢點,但由於這種操作比較少,而查詢很頻繁的情況下還是很好的。bigtable等其實都是這樣做的.
演算法筆記 直接選擇排序
直接選擇排序最好最壞情況時間複雜度均為o n 2 不穩定,其優勢在於最多隻需交換n次,交換操作比比較操作耗時。1.演算法思想 從待排序序列中選擇最小的元素,放入有序序列的末尾 如此迴圈直至待排序序列為空。2.時間複雜度 最好情況 o n 2 序列正序有序,無需交換元素,但比較時間為o n 2 最壞情...
C 演算法筆記 選擇排序SelectSort
選擇排序是一種簡單直觀的排序演算法。它的工作原理是 第一次從待排序的資料元素中選出最小 或最大 的乙個元素,存放在序列的起始位置,然後再從剩餘的末排序元素中尋找到最小 或最大 元素,然後放到已排序的序列的末尾,以此類推。直到全部待排序的資料元素的個數為零。選擇排序 static void selec...
演算法篇 選擇排序演算法
嘿嘿,不要怪我啦,別的都看不懂,就從最基本的開始講解!選擇排序演算法思想 首先在未排序序列中找到最小 大 元素,存放到排序序列的起始位置,然後,再從剩餘的未排序的元素中繼續尋找最小 大 元素,然後放到已排序的末尾。直到所有元素均排序完畢。實現 對於乙個無序的序列我們可以通過n 1趟排序得到排序結果。...