1. 程式人生 > >Java的快速排序----在程序執行緒模擬實驗中遇到的排序問題

Java的快速排序----在程序執行緒模擬實驗中遇到的排序問題

前言:最近作業系統課需要完成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

相關推薦

Java快速排序----在程序執行模擬實驗遇到的排序問題

前言:最近作業系統課需要完成PCB程序執行緒模擬實驗,老師給的c語言版實現程式碼,想著用java實現一波,然後在其中遇到了排序問題,我採用快速排序的演算法進行優先度排序。本人程式設計菜鳥一隻,不喜勿噴,另外,程式碼中有大量註釋,請做好心理準備... 快速排序原理:基於分治

java學習筆記-多執行程式設計模擬十個人過山洞

編寫多執行緒應用程式,模擬多個人通過一個山洞的模擬。這個山洞每次只能通過一個人,每個人通過山洞的時間為5秒,隨機生成10個人,同時準備過此山洞,顯示一下每次通過山洞人的姓名。   使用執行緒同步,把山洞看做臨界資源,五秒內只允許一個人來訪問。 class cave { p

Java 執行 模擬火車站售票

public class TicketSaleTest{ public static void main(String[] args) throws Exception { Station st = new Station(); Person p1 = new Person(st

java:Map集合模擬鬥地主,多執行模擬搶地主 例項

 原始碼如下: package selfpractice.day4; import java.util.*; //多執行緒模擬搶地,重點程式碼位於loot()方法內 public class Practice_Poker { public static void main(S

Java面向物件與多執行綜合實驗(五)之JDBC

本次程式碼沿用第三次中的User.java Administrator.java Operator.java Browser.java和Doc.java 以及第四次中的LoginWindow.java MenuWindow.java UserWindow.java UpDownloadWin

Java面向物件與多執行綜合實驗(四)之GUI設計

瞭解Java圖形介面程式的基本結構;掌握Java佈局管理和常用元件的使用;掌握Java事件處理機制。 實驗內容 編寫程式,將前面課程所編寫的檔案管理系統改編為圖形使用者介面。要求程式介面選用合適的佈局,綜合使用選單、按鈕、文字框、密碼框、下拉列表、檔案對話方塊等元件,實現良好的人機介面。

Java面向物件與多執行綜合實驗(三)之輸入輸出流

瞭解Java中I/O流的概念和種類;掌握位元組流處理和字元流處理,包括File類,InputStream/OutputStream及其子類,Reader/Writer及其子類;熟練掌握檔案的順序處理,隨機訪問處理;熟悉物件序列化的概念和方法。 編寫程式,實現檔案管理系統中的檔案上傳/下載模組

Java面向物件與多執行綜合實驗(二)之 異常處理

理解異常的基本概念;瞭解Java異常的層次結構;熟悉並掌握Java異常的捕獲處理方法。 (1)閱讀Java™ Platform, Standard Edition 8 API Specification文件,瞭解後續程式設計中將要處理的IOException及其子類FileNotFoundE

Java面向物件與多執行綜合實驗(一)之封裝、繼承與多型

編寫一個程式,實現檔案管理系統中的使用者管理模組。要求模組中實現使用者的模擬登入過程。通過使用者輸入,獲取使用者名稱和口令;與事先記錄在程式中的使用者資訊進行對比,通過口令驗證後才能使用系統。使用者分為系統管理人員、檔案錄入人員,檔案瀏覽人員三類,相關類圖如下所示。 (1)要求在使用者類中

Java程序執行之間的區別和聯絡

執行緒是什麼?程序是什麼?二者有什麼區別和聯絡? 執行緒是CPU獨立執行和獨立排程的基本單位; 程序是資源分配的基本單位; 兩者的聯絡: 程序和執行緒都是作業系統所執行的程式執行的基本單元。 區別: 程序具有獨立的空間地址,一個程序崩潰後,在保護模

-1-5 java執行緒 概念 程序 執行緒區別聯絡 java建立執行緒方式 執行緒執行緒池概念 執行緒安全 同步 同步程式碼塊 Lock鎖 sleep()和wait()方法的區別 為什麼wait(),notify(),notifyAll()等方法都定義在O

 本文關鍵詞: java 多執行緒 概念 程序 執行緒區別聯絡 java建立執行緒方式 執行緒組 執行緒池概念 執行緒安全 同步 同步程式碼塊 Lock鎖  sleep()和wait()方法的區別 為什麼wait(),notify(),notifyAll()等方法都定義在Object類中 多執行緒

JAVA學習之路(多執行)---模擬售票(細解)

首先看題目描述: 假設有火車票100張,建立4個執行緒模擬4個售票點,每100ms售出一張,打印出售票過程,格式如下: 視窗3:賣出第100張票 視窗4:賣出第99張票  ............ ............ 簡單的思路就是建立一個類,首先肯定要去繼承Thread。開啟執行

JAVA執行模擬火車站賣票

package com.nisec.myapplication; public class test { static int tickets = 10; public sta

Java執行模擬售票系統

Java建立多執行緒的兩種基本方法:方法1.繼承Thread類(1)定義子類,繼承Thread類,重寫該類的run()方法作為執行緒執行體;(2)建立該子類的例項作為執行緒物件;(3)呼叫執行緒物件的start()方法來啟動執行緒;我們以模擬火車售票系統為例:public c

Java執行 模擬銀行ATM實時存取錢

近期想回顧一些知識: 一、Java 多執行緒 一條執行緒指的是程序中一個單一順序的控制流,一個程序中可以併發多個執行緒,每條執行緒並行執行不同的任務。多執行緒是多工的一種特別的形式,但多執行緒使用了更小的資源開銷。這裡定義和執行緒相關的另一個術

Linux程序執行實驗

實驗1 程序 1.目的 通過觀察、分析實驗現象,深入理解程序及程序在排程執行和記憶體空間等方面的特點,掌握在POSIX 規範中fork和kill系統呼叫的功能和使用。 實驗前準備 學習man 命令的用法,通過它檢視fork 和kill 系統呼叫的

java執行模擬loadrunner進行壓測

package syttest; /** * @author yuzhuliu: * @version 建立時間:2017年9月26日 下午11:58:21 * 類說明 */ public

十一、JVM(HotSpot)Java記憶體模型與執行

注:本博文主要是基於JDK1.7會適當加入1.8內容。 1、Java記憶體模型 記憶體模型:在特定的操作協議下,對特定的記憶體或快取記憶體進行讀寫訪問的抽象過程。不同的物理機擁有不一樣的記憶體模型,而Java虛擬機器也擁有自己的記憶體模型。 主要目標:定義程式中各個變數的訪問規則,

筆記:Java實現三個執行A B C,BC執行執行完再執行A線

final Lock lc = new ReentrantLock(); .. run() { lc.lock(); ... lc.unlock(); } 可能開啟方式不對吧,沒實現! 改用join() 可以實現(BC與A以單執行緒模式執行),程式碼如下: package