编写以下方法,使用第一个元素对列表进行划分,该元素称为支点。
public static int partition(int[] list)
划分后,列表中的元素被重新安排,在支点元素之前的元素都小于或者等于该元素,而之后的元素都大于该元素。方法返回支点元素位于新列表的下标。例如,假设列表是[5,2,9,3,8],划分后,列表变为[3,2,5,9,8]。最多进行list.length次比较来实现该方法。
编写一个程序,提示用户输入一个列表,然后显示划分后的列表。注意,输入的第一个数字表示列表中元素的个数。该数字不是列表的一部分。
提示:快速排序的一次排序
package trial;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
/**
* @create: 2023/3/22
* @Description:
* @FileName: Partition
*/
public class Partition {
public static void main(String[] args) {
// 数组
// SecureRandom random = new SecureRandom();
// int[] list = new int[10];
// for (int i = 0; i < 10; i++) {
// list[i] = random.nextInt(10);
// }
//
// System.out.println("原数组:" + Arrays.toString(list));
// int temp = partition(list);
// System.out.println("新数组:" + Arrays.toString(list) + "\n支点下标:" + temp + "\t\t支点:" + list[temp]);
// 泛型列表
SecureRandom random = new SecureRandom();
List<Character> list = new ArrayList<>(10);
for (int i = 0; i < 10; i++) {
list.add((char) (random.nextInt(10) + 'a'));
}
System.out.println("原列表:" + list);
int temp = partition(list);
System.out.println("新列表:" + list + "\n支点下标:" + temp);
}
private static int partition(int[] list) {
return partition(list, 0, list.length - 1);
}
private static int partition(int[] list, int low, int high) {
int i = low, j = high;
int temp = list[low];
while (i < j) {
while (i < j && list[j] > temp) --j;
while (i < j && list[i] <= temp) ++i;
if (i < j) {
int t = list[j];
list[j] = list[i];
list[i] = t;
}
}
list[low] = list[i];
list[i] = temp;
return i;
}
/** 可用于继承了Comparable可泛型类 */
private static <E extends Comparable<E>> int partition(List<E> list) {
int i = 0, j = list.size() - 1;
E temp = list.get(i);
while (i < j) {
// list.get(j).compareTo(temp) > 0 , 快速排序是>=0,但这里只能>0,否则在右侧可能存在相等的数
while (i < j && list.get(j).compareTo(temp) > 0) --j;
while (i < j && list.get(i).compareTo(temp) <= 0) ++i;
if (i < j) {
E t = list.get(j);
list.set(j, list.get(i));
list.set(i, t);
}
}
list.set(0, list.get(i));
list.set(i, temp);
return i;
}
}