找出第二小元素(算法导论第三版9.1-1题)
时间复杂度Θ(n)
比较次数n+⌈lgn⌉−2次
思路:将元素每次分成2部分,第一部分和第二部分元素成对比较。最终获得最小的元素,记录那些和最小元素比较后的失败的元素,第二小元素就在其中。
原理:第二小元素只有和最小元素比才会失败,其他元素和其比都它都能胜出。所以,第二小元素一定在那些和最小元素比较后失败的元素中。第二小元素一定能和最小元素比较,因为除了和最小元素比以外它都能胜出。
int find_second_smallest_element(int *array,int length){vector<int> new_win;vector<int> old_win;for (int i = 0; i < length; ++i) {old_win.push_back(i);}vector<vector<int>> loss(length);int current_length = length;int remainder ;int win_index,loss_index;while (current_length>1){remainder = current_length % 2;if(remainder!=0){new_win.push_back(old_win[current_length / 2]);}for (int i = 0; i < current_length/2; ++i){if(array[old_win[i]]<=array[old_win[current_length-i-1]]){win_index = old_win[i];loss_index = old_win[current_length-i-1];}else{win_index = old_win[current_length-i-1];loss_index = old_win[i];}new_win.push_back(win_index);loss[win_index].push_back(loss_index);}current_length = new_win.size();old_win.clear();for (int i = 0; i < new_win.size(); ++i) {old_win.push_back(new_win[i]);}new_win.clear();}int second_smallest = loss[win_index][0];for (int i = 1; i < loss[win_index].size(); ++i) {if(array[loss[win_index][i]] < array[second_smallest]){second_smallest = loss[win_index][i];}}return array[second_smallest];
}