數據結構之隊列—輪渡模擬


一、簡單介紹

    這是在博客園潛水幾個月第一次開始想要寫點東西,一是記錄自己的學習過程,二是和大家分享同時接受大家的指正,再者可以多交一些朋友,我微博地址在公告欄里。。。。這是最近上數據結構時的練習題,首先是隊列的實現,再用隊列去模擬解決一個實際問題——輪渡模擬。

二、問題分析   

2.1 問題描述:

  • 輪渡模擬:有一個渡口,每條渡船能一次性裝載10輛汽車過河,車輛分為客車和貨車兩類。
  • 上渡輪有如下規定:同類汽車先到先上船,客車先於貨車上船,輪渡每10分鍾一班。
  • 模擬一小時內汽車上渡輪的過程。
  • 汽車:包含一個汽車類型屬性,一個到達時間屬性,到達時間隨機產生。
  • 輪渡:包含一個裝車情況的屬性,一個出發時間的屬性。
  • 輸出:1小時內六班輪渡的裝車情況。

2.2 實現說明:

  • 輪渡不管是否裝滿10秒鍾一班,一共進行6班共一分鍾;
  • 期間的汽車到來時間及類型是隨機的;
  • 初始當前已有一班渡輪停靠在渡口;

    當拿到這個問題時,分析問題后覺得要比較好的使各個事件不相互影響地模擬輪渡情況,需要用到多線程,但因為以前都是在Linux環境下編程,沒有在Windows上實現過多線程編程,所以也不知道在具體實現中是否會存在什么問題。實現時在主函數中創建了三個線程:其中兩個線程分別是客車和貨車隨機產生(到達),並攜帶時間信息進入到相應的隊列;還有一個是用於做計時器用。

 

三、實現代碼

3.1測試

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <windows.h>
#include <process.h>
#include "sqQueue.h"                             //包含自定義隊列類
using namespace std;

#define MAX_NUM 10                               //渡輪最大裝載數量
typedef enum{PassengerCar, FreightCar}CarType;   //汽車類型
typedef struct  
{
    CarType type;                                //汽車類型
    time_t arriveTime;                           //汽車到達時間
}Car;

typedef struct  
{
    int size;                                    //渡輪當前裝載汽車數量
    time_t startTime;                            //渡輪出發時間
}Ferry;

SqQueue<Car> pCarQueue(61);                      //定義隊列,用於存放客車的隊列,模擬一分鍾最多60輛汽車
SqQueue<Car> fCarQueue(61);                      //定義隊列,用於存放貨車的隊列
int startTimeFlag = 0;                           //定義渡輪出發標志
int countLength = 6;                             //計數長度
unsigned _stdcall threadCountFun(void* pArguments)
{
    while (countLength > 0)
    {
        Sleep(10000);                            //計數10秒
        startTimeFlag = 1;
        countLength--;
    }
    return 0;
}
bool ferryFun() //函數:處理渡輪到達,裝載,出發等 { int count = 1; //渡輪計數 while (count<7) { Ferry ferry; ferry.size = 0; //初始輪渡裝載汽車數量 while(1) { if (ferry.size < 10 ) //輪渡未滿 { if (!pCarQueue.isEmpty_SqQueue() && !fCarQueue.isEmpty_SqQueue() && pCarQueue.top_SqQueue().arriveTime == fCarQueue.top_SqQueue().arriveTime) { //當兩隊列對頭汽車到達時間相同時,客車先上船 cout<<"一輛客車上船...其到達渡口時間:"; cout<<ctime(&pCarQueue.top_SqQueue().arriveTime); pCarQueue.pop_SqQueue(); ferry.size++; }
         
else if (!pCarQueue.isEmpty_SqQueue() && !fCarQueue.isEmpty_SqQueue() && pCarQueue.top_SqQueue().arriveTime < fCarQueue.top_SqQueue().arriveTime) { //客車先到 cout<<"一輛客車上船...其到達渡口時間:"; cout<<ctime(&pCarQueue.top_SqQueue().arriveTime); pCarQueue.pop_SqQueue(); ferry.size++; }
         
else if(!fCarQueue.isEmpty_SqQueue()) //貨車先到 { cout<<"一輛貨車上船...其到達渡口時間:"; cout<<ctime(&fCarQueue.top_SqQueue().arriveTime); fCarQueue.pop_SqQueue(); ferry.size++; } }
if (1 == startTimeFlag) { time(&ferry.startTime); cout<<"時間過去"<<10*count<<"分鍾"; cout<<""<<count<<"條渡輪開走,"<<"裝有汽車"; cout<<ferry.size<<""<<",出發時間:"<<ctime(&ferry.startTime); count++; startTimeFlag = 0; break; }
} }
return true; } unsigned _stdcall threadPCarFun(void* pArguments) //客車處理函數 { srand(time(0)); while (!pCarQueue.isFull_SqQueue()) { Car car; if (1 == rand()%14) //1(客車) { car.type = PassengerCar; time(&car.arriveTime); //記錄到達時間 pCarQueue.push_SqQueue(car); // cout<<"P: "<<car.arriveTime<<endl; } Sleep(200); //200和10意義:每2毫秒中有十四分之一概率產生(到達)一輛汽車(客車和貨車) } return 0; } unsigned _stdcall threadFCarFun(void* pArguments) //貨車處理函數 { srand(time(0)); while (!fCarQueue.isFull_SqQueue()) { Car car; if(2 == rand()%14) //2(貨車) { car.type = FreightCar; time(&car.arriveTime); //記錄到達時間 fCarQueue.push_SqQueue(car); // cout<<"H: "<<car.arriveTime<<endl; } Sleep(200); //200和14意義:每1毫秒中有十分之一概率產生(到達)一輛汽車 } //測試這個頻率能看到裝滿和沒裝滿的情況 return 0; } int main(int argc, char** argv) { HANDLE hThread_P, hThread_F, hThread_Count; unsigned int threadID_P, threadID_F, threadID_Count; hThread_P = (HANDLE) _beginthreadex(NULL, 0, &threadPCarFun, NULL, 0, &threadID_P); hThread_F = (HANDLE) _beginthreadex(NULL, 0, &threadFCarFun, NULL, 0, &threadID_F); hThread_Count = (HANDLE) _beginthreadex(NULL, 0, &threadCountFun, NULL, 0, &threadID_Count); ferryFun(); cout<<"\n汽車排隊中....直至隊滿..."<<endl; WaitForSingleObject(hThread_P, INFINITE ); WaitForSingleObject(hThread_F, INFINITE ); WaitForSingleObject(hThread_Count, INFINITE );
CloseHandle(hThread_P); CloseHandle(hThread_F); CloseHandle(hThread_Count);
return 0; }

運行結果:

 

3.2以下是自己用模板類實現的循環隊列:

自定義隊列類(sqQueue.h)
#ifndef SQQUEUE_H
#define SQQUEUE_H

#define  Q_MAX_LENGTH 100

template <typename T>
class SqQueue
{
public:
    SqQueue(int length_SqQueue = Q_MAX_LENGTH);
    virtual ~SqQueue();
    bool push_SqQueue(const T& e);
    bool pop_SqQueue();
    bool isEmpty_SqQueue();
    bool isFull_SqQueue();
    T& top_SqQueue();
    const T& top_SqQueue()const;
    int size_SqQueue();
    void display_SqQueue();
private:
    T* data;
    int front;
    int rear;
    int length;
};
/*構造函數,初始化隊列*/
template <typename T>
SqQueue<T>::SqQueue(int length_SqQueue)
{
    data = new T[length_SqQueue];
    front = rear = 0;
    length = length_SqQueue;
}
/*析構函數*/
template <typename T>
SqQueue<T>::~SqQueue()
{
    delete []data;
}
/*判空操作 */
template <typename T>
bool SqQueue<T>::isEmpty_SqQueue()
{
    if (front == rear)
        return true;
    else
        return false;
}
/*判滿操作*/
template <typename T>
bool SqQueue<T>::isFull_SqQueue()
{
    if ((rear+1)%length == front)
        return true;
    else
        return false;
}
/*入隊操作*/
template <typename T>
bool SqQueue<T>::push_SqQueue(const T& e)
{
    if (!isFull_SqQueue())
    {
        data[rear] = e;
        rear = (rear+1)%length;
        return true;
    }
    return false;
}
/*出隊操作*/
template <typename T>
bool SqQueue<T>::pop_SqQueue()
{
    if (!isEmpty_SqQueue())
    {
        front = (front+1)%length;
    }
    return false;
}
/*得到對頭元素*/
template <typename T>
T& SqQueue<T>::top_SqQueue()
{
    if (!isEmpty_SqQueue())
    {
        return data[front];
    }
//    cout<<"隊列空"<<endl;
}
/*得到對頭元素, const版本*/
template <typename T>
const T& SqQueue<T>::top_SqQueue()const
{
    if (!isEmpty_SqQueue())
    {
        return data[front];
    }
//    cout<<"隊列空"<<endl;
}
/*測隊長*/
template <typename T>
int SqQueue<T>::size_SqQueue()
{
    return (rear-front+length)%length;
}
/*遍歷打印操作*/
template <typename T>
void SqQueue<T>::display_SqQueue()
{
    int i = front;
    while (i != rear)
    {
        std::cout<<data[i]<<" ";
        i = (i+1)%length;
    }
    std::cout<<endl;
}

#endif


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM