国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

山東大學(xué)數(shù)據(jù)結(jié)構(gòu)課設(shè)第一部分實(shí)驗(yàn)二——外排序

這篇具有很好參考價(jià)值的文章主要介紹了山東大學(xué)數(shù)據(jù)結(jié)構(gòu)課設(shè)第一部分實(shí)驗(yàn)二——外排序。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

題目要求:

應(yīng)用輸者樹結(jié)構(gòu)模擬實(shí)現(xiàn)外排序。

基本要求:

1. 設(shè)計(jì)并實(shí)現(xiàn) 最小輸者樹 結(jié)構(gòu) ADT , ADT 中應(yīng)包括初始化、返回贏者,重構(gòu)等基本操作。
2. 應(yīng)用最小輸者樹設(shè)計(jì)實(shí)現(xiàn)外排序,外部排序中的生成最初歸并串以及 K 路歸并都應(yīng)用最小輸者樹結(jié)構(gòu)實(shí)現(xiàn);
3. 驗(yàn)證你所實(shí)現(xiàn)的外排序的正確性。
1 )隨機(jī)創(chuàng)建一個(gè)較長的文件作為外排序的初始數(shù)據(jù),設(shè)置最小輸者樹中選手的個(gè)數(shù),驗(yàn)證生成最初歸并串的正確性。獲得最初歸并串的個(gè)數(shù)及最初歸并串文件,每一最初歸并串使用一個(gè)文件。
(2)使用以上生成的歸并串,設(shè)置歸并路數(shù),驗(yàn)證 K 路歸并的正確性。獲得 K 路歸并中各趟的結(jié)果,每一趟的結(jié)果使用一個(gè)文件。
*4. 獲得外排序的訪問磁盤次數(shù),并分析其影響因素。

代碼實(shí)現(xiàn):

最小輸者樹:

losetree.h:

#ifndef _LOSETREE_H
#define _LOSETREE_H

#include<bits/stdc++.h>
using namespace std;

const int MAX_INT = 2147483647;        //設(shè)置int的最大值
const int MIN_INT = -2147483648;       //設(shè)置int的最小值

struct Node           //設(shè)置Node節(jié)點(diǎn),用來進(jìn)行初始?xì)w并段的生成
{
	int id;           //優(yōu)先級(jí)
	int number;
	bool operator<(const Node& a)const     
	{
		if (id != a.id)        //如果優(yōu)先級(jí)不同那么就先比較優(yōu)先級(jí),如果優(yōu)先級(jí)相同,則比較數(shù)值
			return id < a.id;
		else
			return number < a.number;
	}
};

template<class T>
class losetree
{
public:
	losetree(T* a,int num);
	T winner();
	T player1();
	void reinit(T element);
private:
	int number;
	T* loser;      //輸者樹
	int* winer;    //記錄每次的贏者下標(biāo)
	T* player;     //贏者樹
};
#endif 

losetree.cpp:

#include"losetree.h"

template<class T>
losetree<T>::losetree(T* a,int num)      //復(fù)雜度為O(n)
{
	number = num;
	player = new T[2 * num]();
	winer = new int[num * 2]();
	loser = new T[num]();
	for (int i = number; i < 2 * number; i++)
	{
		player[i] = a[i - number];
		winer[i] = i;
	}
	for (int i = number - 1; i > 0; i--) 
	{
		if (player[2 * i] < player[2 * i + 1])
		{
			player[i] = player[2 * i];
			loser[i] = player[2 * i + 1];
			winer[i] = winer[2 * i];
		}
		else
		{
			player[i] = player[2 * i + 1];
			loser[i] = player[2 * i];
			winer[i] = winer[2 * i + 1];
		}
	}
	loser[0] = player[winer[1]];         //記錄最小值
}

template<class T>
T losetree<T>::winner()
{
	return loser[0];         //loser[0]中存儲(chǔ)的是最小值
}
template<class T>
T losetree<T>::player1()
{
	return winer[1];         //最小值的下標(biāo)
}

template<class T>
void losetree<T>::reinit(T element)        //復(fù)雜度為O(logn)
{
	player[winer[1]] = element;
	for (int i = winer[1] / 2; i > 0; i = i / 2)        //重構(gòu)時(shí)需要將最小值的元素與其父節(jié)點(diǎn)相比較,直到根節(jié)點(diǎn)為止
	{
		if (player[2 * i] < player[2 * i + 1])
		{
			player[i] = player[2 * i];
			loser[i] = player[2 * i + 1];
			winer[i] = winer[2 * i];
		}
		else
		{
			player[i] = player[2 * i + 1];
			loser[i] = player[2 * i];
			winer[i] = winer[2 * i + 1];
		}
	}
	loser[0] = player[winer[1]];         //記錄最小值
}

外排序:

Merge.h:

#ifndef _MERGE_H
#define _MERGE_H
#include"losetree.cpp"

template<class T>
class Merge
{
public:
	Merge(int _Size, int _NumberOfCombine);
	void outputname(string s1);         //設(shè)置歸并段的名稱  
	void devide(string name);           //初始?xì)w并段的生成
	void combine();                     //歸并段的合并
	int NumberOfTimes();                //磁盤的讀取次數(shù)
private:
	int Size;        //輸者樹的大小
	int NumberOfCombine;        //記錄歸并路數(shù)
	int NumberOfFile;           //記錄每次產(chǎn)生的歸并段個(gè)數(shù)
	string s, s1;               //產(chǎn)生歸并段的名稱
	string answer;              //最終輸出的文件的名稱
	int times;       //記錄磁盤的讀取次數(shù)
};
#endif 

Merge.cpp:

#include"Merge.h"

template<class T>
Merge<T>::Merge(int _Size, int _NumberOfCombine)
{
	Size = _Size;
	NumberOfCombine = _NumberOfCombine;
	NumberOfFile = 0;
	s1 = ".txt";
	answer = "output.txt";
	times = 0;
}

template<class T>
void Merge<T>::outputname(string s)          //設(shè)置歸并段的名稱  
{
	this->s = s;
}

template<class T>
void Merge<T>::devide(string name)           //初始?xì)w并段的生成
{
	ifstream victory(name, ios::in);         //打開名為name的文件
	int number;
	victory >> number;                       //從文件中讀取數(shù)據(jù)的個(gè)數(shù)

	times++;

	Node* well = new Node[Size];             //建立一個(gè)大小為輸者樹大小的數(shù)組
	for (int i = 0; i < Size; i++)
	{
		victory >> well[i].number;
		well[i].id = 1;                      //初始優(yōu)先級(jí)均為1
	}

	losetree<Node> defeat(well, Size);
	int num = 0;
	while (1)
	{
		victory >> num;
		if (victory.eof())                   //判斷文件末位,文件到末尾則退出循環(huán)
			break;

		Node p1 = defeat.winner();

		Node p;
		p.number = num;
		if (num > p1.number)                  //如果num比最小輸者樹的最小值大,則優(yōu)先級(jí)相同,反之則優(yōu)先級(jí)+1
		{
			p.id = p1.id;
		}
		else
		{
			p.id = p1.id + 1;
			NumberOfFile = max(NumberOfFile, p.id);              //得到產(chǎn)生的初始?xì)w并段的個(gè)數(shù)
		}

		defeat.reinit(p);                     //重構(gòu)
		string s3 = s + "0-" + to_string(p1.id) + s1;        
		ofstream fff(s3, ios::app);          //ios::app在文件末位接著輸出,ios::out重新在文件中輸出
		fff << p1.number << ' ';
		fff.close();

		times++;        //由于打開了s3文件因此,尋盤次數(shù)加一
	}
	while (1)           //將輸者樹中剩余的數(shù)輸出
	{
		if (defeat.winner().number == MAX_INT)
			break;

		Node p1 = defeat.winner();

		Node p;         //p的優(yōu)先級(jí)得是最低,并且值是最大
		p.id = MAX_INT;
		p.number = MAX_INT;

		defeat.reinit(p);
		string s3 = s + "0-" + to_string(p1.id) + s1;
		ofstream fff(s3, ios::app);
		fff << p1.number << ' ';
		fff.close();

		times++;
	}
}

template<class T>
void Merge<T>::combine()                  //歸并段的合并
{
	for (int h = 0; NumberOfFile != 1; h++)
	{
		int* he = new int[NumberOfCombine];
		ifstream* infile = new ifstream[NumberOfFile + 1];             //將所有的歸并段都放入緩沖區(qū)
		for (int i = 1; i <= NumberOfFile; i++)
		{
			infile[i].open(s + to_string(h) + "-" + to_string(i) + s1, ios::in);
			times++;
		}


		int j = 0;
		for (; j < ceil((double)NumberOfFile / (double)NumberOfCombine); j++)             //將所有的文件進(jìn)行k路歸并
		{
			string out;
			if (NumberOfFile <= NumberOfCombine)                  //判斷產(chǎn)生的文件是否是最終的歸并結(jié)果,對(duì)輸出的文件名進(jìn)行定義
			{
				out = answer;
			}
			else
			{
				out = s + to_string(h + 1) + "-" + to_string(j + 1) + s1;
			}

			ofstream outfile(out, ios::out);

			times++;
			for (int i = 1; i <= NumberOfCombine; i++)
			{
				if (j * NumberOfCombine + i >= NumberOfFile + 1)           //判斷剩余的文件個(gè)數(shù)是否小于歸并路數(shù),如果小于則要將這個(gè)數(shù)組中的差值用最大值進(jìn)行補(bǔ)充
				{
					he[i - 1] = MAX_INT;
				}
				else

					infile[j * NumberOfCombine + i] >> he[i - 1];
			}

			losetree<int> L(he, NumberOfCombine);

			while (L.winner() != MAX_INT)
			{
				outfile << L.winner() << ' ';
				for (int f = 0; f < NumberOfCombine; f++)
				{
					if (L.player1() == f + NumberOfCombine && j * NumberOfCombine + 1 + f < NumberOfFile + 1)         //得到最小輸者樹的最小值下標(biāo)是具體的那個(gè)文件,此時(shí)還要注意有可能存在剩余的文件個(gè)數(shù)小于歸并路數(shù)的情況
					{
						int u = 0;
						infile[j * NumberOfCombine + 1 + f] >> u;
						if (infile[j * NumberOfCombine + 1 + f].eof())              //如果到文件末位則將最大值輸入到輸者樹中,然后進(jìn)行重排即可
							u = MAX_INT;
						L.reinit(u);
						break;
					}
				}
			}
			outfile.close();
		}

		for (int i = 1; i <= NumberOfFile; i++)
			infile[i].close();
		NumberOfFile = j;
	}
}

template<class T>                 //磁盤的讀取次數(shù)
int Merge<T>::NumberOfTimes()
{
	return times;
}


//文件末位如果有空格,則需要先將數(shù)據(jù)讀入,因?yàn)閷?shù)據(jù)放入緩沖區(qū)后,eof函數(shù)在將最后一個(gè)數(shù)據(jù)放入緩沖區(qū)后,并沒有到達(dá)文件的末尾,還需要再讀入一位最后的空格,此時(shí)會(huì)將緩沖區(qū)的數(shù)讀入,也就是最后一個(gè)數(shù)據(jù)再讀一遍
//文件末位沒有空格,那就先判斷是否到文件末位,再讀入數(shù)據(jù)就可以了

主函數(shù):

main.cpp:文章來源地址http://www.zghlxwxcb.cn/news/detail-859214.html

#include"Merge.cpp"

bool judge(string s)              //判斷文件是否可以打開
{
	ifstream Try(s, ios::in);
	if (!Try.is_open())
	{
		return false;
	}
	Try.close();
	return true;
}

int main()
{
	cout << "請(qǐng)輸入輸者樹的大小:" << endl;
	int Size;
	cin >> Size;

	cout << "請(qǐng)輸入要實(shí)現(xiàn)幾路歸并:" << endl;
	int Several;
	cin >> Several;

	Merge<int> M(Size, Several);

	cout << "請(qǐng)輸入要生成的文件名稱:" << endl;
	string s;
	cin >> s;
	M.outputname(s);

	cout << "請(qǐng)輸入要外排序的文件名稱:" << endl;
	string name;
	cin >> name;
	while (!judge(name)) {
		cout << "請(qǐng)重新輸入要外排序的文件名稱:" << endl;
		cin >> name;
	}
	M.devide(name);

	M.combine();

	cout << "磁盤訪問次數(shù)為:" << endl;
	cout << M.NumberOfTimes() << endl;
}

到了這里,關(guān)于山東大學(xué)數(shù)據(jù)結(jié)構(gòu)課設(shè)第一部分實(shí)驗(yàn)二——外排序的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【飛機(jī)票售票系統(tǒng)】山東大學(xué)大二暑期數(shù)據(jù)庫課程設(shè)計(jì)項(xiàng)目SSM+VUE2前后端分離(含源碼)

    【飛機(jī)票售票系統(tǒng)】山東大學(xué)大二暑期數(shù)據(jù)庫課程設(shè)計(jì)項(xiàng)目SSM+VUE2前后端分離(含源碼)

    一、系統(tǒng)概述 二、需求分析 2.1 系統(tǒng)功能分析 2.2 系統(tǒng)數(shù)據(jù)分析 2.3 系統(tǒng)非功能分析 三、系統(tǒng)設(shè)計(jì) 3.1 應(yīng)用程序設(shè)計(jì) 3.2 數(shù)據(jù)庫設(shè)計(jì) 3.2.1 概念設(shè)計(jì) 3.2.2 邏輯設(shè)計(jì) 四、系統(tǒng)實(shí)現(xiàn) 4.1 關(guān)鍵技術(shù)實(shí)現(xiàn) 4.2 功能實(shí)現(xiàn) 五、系統(tǒng)測試 六、問題記錄 飛機(jī)票售票系統(tǒng),分為兩個(gè)角色,系統(tǒng)管理

    2024年02月09日
    瀏覽(31)
  • 山東大學(xué)增強(qiáng)現(xiàn)實(shí)實(shí)驗(yàn)四

    山東大學(xué)增強(qiáng)現(xiàn)實(shí)實(shí)驗(yàn)四

    注意:本人尚處在opencv的入門學(xué)習(xí)階段,本博客僅為個(gè)人學(xué)習(xí)筆記見解,如有不當(dāng),歡迎指出 (實(shí)驗(yàn)/理論)平面標(biāo)志物的視覺跟蹤,要求: 選擇一個(gè)標(biāo)志物,可以是人工標(biāo)志物,也可以是自然標(biāo)志物;實(shí)現(xiàn)和實(shí)驗(yàn)二相同的效果。 用手機(jī)或攝像頭拍攝標(biāo)志物的影像,建議讀取視

    2024年02月08日
    瀏覽(77)
  • 整數(shù)序列(山東大學(xué)考研機(jī)試題)

    整數(shù)序列(山東大學(xué)考研機(jī)試題)

    題目鏈接:3717. 整數(shù)序列 - AcWing題庫

    2024年02月13日
    瀏覽(25)
  • 2021山東大學(xué)眾智期末復(fù)習(xí)筆記

    2021山東大學(xué)眾智期末復(fù)習(xí)筆記

    目錄 社交網(wǎng)絡(luò) 同質(zhì)性 正負(fù)關(guān)系 小世界 搜索引擎 博弈論 市場 權(quán)力 從眾 新事物的擴(kuò)散 信息不對(duì)稱 流?病和線粒體夏娃 強(qiáng)連通圖:有向圖G中,任意兩點(diǎn)可以相互到達(dá)。 有向圖的強(qiáng)連通分量:有向圖中的極大強(qiáng)連通子圖。 三元閉包:如果兩個(gè)互不相識(shí)的人有了一個(gè)共同的朋

    2023年04月08日
    瀏覽(30)
  • 山東大學(xué)計(jì)算機(jī)網(wǎng)絡(luò)期末

    山東大學(xué)計(jì)算機(jī)網(wǎng)絡(luò)期末

    內(nèi)容僅供參考。如有錯(cuò)誤之處,敬請(qǐng)指正! 第一章 概述 第二章 物理層 第三章 數(shù)據(jù)鏈路層 第四章 介質(zhì)訪問子層 第五章 網(wǎng)絡(luò)層 第六章 傳輸層 第七章 應(yīng)用層 1.基本概念 計(jì)算機(jī)網(wǎng)絡(luò)定義: 表示一組通過單一技術(shù)相互連接起來的自主計(jì)算機(jī)集合。 分布式系統(tǒng): 是建立在網(wǎng)絡(luò)

    2024年02月03日
    瀏覽(25)
  • 山東大學(xué)數(shù)字圖像處理實(shí)驗(yàn)(一)

    山東大學(xué)數(shù)字圖像處理實(shí)驗(yàn)(一)

    題目:加載并顯示圖像 imread 函數(shù)原型為 imread(const string filename, int flags=1) 這里的 filename 需要的是圖像的路徑。該函數(shù)從文件中加載圖像并返回一個(gè)矩陣,如果圖像不能被讀取,則返回一個(gè)空的矩陣 這里介紹一下不同 flag 的效果 flag=-1 :8位深度,原通道 flag=0 :8位深度,

    2024年02月06日
    瀏覽(17)
  • 山東理工大學(xué)單元測試2重現(xiàn)

    本次單元測試雖然較第一次機(jī)測難度增加,但整體難度與平時(shí)pta練習(xí)相比,難度并不大,一些細(xì)節(jié)同學(xué)們?cè)诳荚嚂r(shí)容易忽略,本次八道題,可關(guān)注第四題的簡便公式,以及第七題的注意事項(xiàng)和第八題運(yùn)行超時(shí)的解決辦法。 7-1 sdut-C語言實(shí)驗(yàn)-A+B for Input-Output Practice (不確定次數(shù)循

    2024年02月05日
    瀏覽(24)
  • 【軟件工程】山東大學(xué)軟件工程復(fù)習(xí)提綱

    【軟件工程】山東大學(xué)軟件工程復(fù)習(xí)提綱

    涵蓋所有考點(diǎn),復(fù)習(xí)絕對(duì)高效,點(diǎn)贊+留郵箱獲取pdf版本 本提綱可以完全摘抄,考試命中率100%,先上考試帶的A4紙: 1. 軟件工程三要素 方法:為軟件開發(fā)提供了“如何做 ”的技術(shù),如項(xiàng)目計(jì)劃與估算、軟件系統(tǒng)需求分析、數(shù)據(jù)結(jié)構(gòu)、系統(tǒng)總體結(jié)構(gòu)的設(shè)計(jì)等; 工具:為軟件工

    2024年02月13日
    瀏覽(30)
  • 圖解基礎(chǔ)排序算法(冒泡、插入、選擇)(山東大學(xué)實(shí)驗(yàn)二)

    圖解基礎(chǔ)排序算法(冒泡、插入、選擇)(山東大學(xué)實(shí)驗(yàn)二)

    ? 目錄 ?前言: ???冒泡排序: 設(shè)定: 分類: 起源: 圖解冒泡: 圖中綠色: 圖中橙色: 整體思路: 交換思路: 核心代碼:? ???圖解插入: 設(shè)定: 插入思路: 整體思路: 核心代碼: ??圖解選擇:? 設(shè)定: 整體思路: 核心代碼:? ??山東大學(xué)實(shí)驗(yàn)二完整代碼:?

    2024年01月17日
    瀏覽(28)
  • 山東大學(xué)電路分析實(shí)驗(yàn)1 萬用表的使用

    山東大學(xué)電路分析實(shí)驗(yàn)1 萬用表的使用

    實(shí)驗(yàn)1? 萬用表的使用 1.1 實(shí)驗(yàn)?zāi)康?1. 了解萬用表的結(jié)構(gòu)和功能; 2. 學(xué)習(xí)使用萬用表測量電阻、電感、電容和二極管的方法; 3. 學(xué)習(xí)使用萬用表測量直流電壓和直流電流的方法; 4. 理解萬用表內(nèi)阻對(duì)測量結(jié)果的影響; 1.2 實(shí)驗(yàn)原理 萬用表是集電壓表、電流表和歐姆表于一體的

    2024年02月06日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包