版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/G_drive/article/details/78691338
前言:最近操作系统课需要完成PCB进程线程模拟实验,老师给的c语言版实现代码,想着用java实现一波,然后在其中遇到了排序问题,我采用快速排序的算法进行优先度排序。本人编程菜鸟一只,不喜勿喷,另外,代码中有大量注释,请做好心理准备...
快速排序原理:基于分治的思想进行排序。选择一个基准值(一般是序列第一个元素的值),一次递归结束时,基准值左边的序列所有元素的值都比基准值小,基准值右边的序列所有元素的值都比基准值大。分别对左右序列递归。最终得到排序完毕的序列。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
System.out.println("请输入进程号?");
//存入总进程数
Scanner s = new Scanner(System.in);
int num = s.nextInt();
//建立进程列表
List<PCB> listOfProcess = new ArrayList();
//初始化进程信息,输入所有进程信息
input(num,listOfProcess);
//显示所有进程
disp(listOfProcess);
//建立对进程进行优先级排列函数
sort(listOfProcess, 0, (listOfProcess.size()-1));
disp(listOfProcess);
}
//建立对进程进行优先级排列函数
private static void sort(List<PCB> listOfProcess, int low, int high) {
/**
* 初始化start、end、key
* start为从前往后的游动下标
* end为从后往前的游动下标
* key是最开始的基准,在本轮递归中是不变的,变的是两个游标上的值
*/
int start = low;
int end = high;
int key = listOfProcess.get(low).getPriority();
/**
* 一切的一切,都是为了分治
* 一轮下来,找到当前队列的关键值,左边的值都比关键值小,右边的值都比关键值大
*/
while (end > start){
/**
* 从后到前
*
* 1、这里为什么还要判断end>start?
* 判断是否逼近结束。
* 啰嗦的解释:因为end不断在变,用于判断从后往前时是否到了与start最近处。
*
* 2、这里为什么判断listOfProcess.get(end).getPriority() >= key?
* 为了end从后往前逼近关键值。
* 是为了从后往前找到第一个比基准小的值,进行交换。确保本次从后往前排序的时候,以基准为标准,end游动下标后面的值比基准大
*/
while (end > start && listOfProcess.get(end).getPriority() >= key){
end--;
}
//start与end值交换,把基准值换到end位置上,此时,end是从end开始往后的队列中,值最小的
if (listOfProcess.get(end).getPriority() <= key){
PCB temp = listOfProcess.get(end);
listOfProcess.set(end, listOfProcess.get(start));
listOfProcess.set(start, temp);
}
//从前往后,道理一样,从前开始保证,start前的都比start小
while (end > start && listOfProcess.get(start).getPriority() <= key){
start++;
}
//start与end值交换,把基准值换到start位置上,此时,start是从start开始往前的队列中,值最大的
if (listOfProcess.get(start).getPriority() >= key){
PCB temp = listOfProcess.get(end);
listOfProcess.set(end, listOfProcess.get(start));
listOfProcess.set(start, temp);
}
}
/**
* 以上是为了找到关键值,接下来的递归才是重中之重
*
* 1、为什么要判断low < start、high > end?
* 因为,当start没有改变时,说明这一段已经排序ok,无需接着往下递归了
*
* 2、start为什么-1,end为什么+1?
* start和end若不重合,两者已经排序好了
* 若重合,则这个重合的地方已经确定排序
*
*/
if (low < start){
sort(listOfProcess, low, start-1);
}
if (high > end){
sort(listOfProcess, end+1, high);
}
}
/*建立进程显示函数,用于显示当前进程*/
private static void disp(List<PCB> listOfProcess) {
System.out.println("qname \t state \t super \t ndtime \t runtime");
for (PCB pcb: listOfProcess) {
System.out.println(pcb.getName()+" \t "+ pcb.getState()+" \t "+pcb.getPriority()+" \t\t "+pcb.getNtime()+" \t\t\t "+pcb.getRtime());
}
}
/*建立进程控制块函数*/
private static void input(int num, List<PCB> listOfProcess) {
Scanner s = new Scanner(System.in);
//填充列表
for (int i = 0; i < num; i++){
System.out.println("输入进程名:");
String name = s.next();
System.out.println("输入进程优先数:");
int priority = s.nextInt();
System.out.println("输入进程运行时间:");
int ntime = s.nextInt();
System.out.println();
//初始化当前进程的PCB
PCB pcb = new PCB(name,"wait",priority,ntime,0);
//加入队列
listOfProcess.add(pcb);
}
}
}
参考原文 https://www.cnblogs.com/hjy9420/p/5032309.html