小內存大文件排序小例子——冒泡、歸併

今天刷博客看到一篇文章,講在有限內存下排序大文件的處理方法,動手寫了個小例子:

大概實現的思想是,我們有能存30個數的內存空間,如何對100個數進行排序
下邊的程序中我將這100個數分成4份分別進行冒泡排序,假使所有的結果輸出至文件中,對這若干個程序再進行歸併排序並將結果輸出。

這段代碼中並沒有對除不盡數據做處理,既 nNums / nGroups 必須沒有餘數纔可以使用,有興趣的可以在這個基礎上優化下。

// ConsoleApplication1.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//

#include "pch.h"
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
int main()
{
	const int nNums = 100;
	const int nGroups = 4;
	const int nRandomLimit = 100;
	vector<int> vnOriginal(0);
	std::cout << "Original data:" <<endl;
	for (int i = 0; i < nNums; i++)
	{
		vnOriginal.push_back(rand() % nRandomLimit);   //產生nNums範圍在nRandomLimit的隨機數
		std::cout << vnOriginal[i] << " ";
	}
	std::cout << std::endl;
	vector< vector<int> > vGroup; //分割成nGroups份
	for (int i = 0; i < nGroups; i++)
	{
		std::cout << "group divide" << i << std::endl;
		vector<int> tmp;
		for (int j = 0; j < nNums / nGroups; j++)
		{
			tmp.push_back(vnOriginal[i * nNums / nGroups + j]);
			std::cout << tmp[j] << " ";
		}
		std::cout << std::endl;
		vGroup.push_back(tmp);
		tmp.clear();
	}
	for (int i = 0; i < nGroups; i++)
	{
		int nFlgIndex = 0;
		for (int j = 0; j < vGroup.at(i).size() - 1; j++)
		{
			bool bIsChange = false;
			for (int k = 0; k < vGroup.at(i).size() - nFlgIndex - 1; k++)
			{
				if (vGroup[i][k] > vGroup[i][k + 1])
				{
					swap(vGroup[i][k], vGroup[i][k + 1]);
					bIsChange = true;
				}
			}
			if (bIsChange == false)
				break;
			nFlgIndex++;
		}
	}

	for (int i = 0; i < nGroups; i++)
	{
		std::cout << "group" << i << std::endl;
		for (int j = 0; j < vGroup.at(i).size(); j++)
		{
			std::cout << vGroup[i][j] << " ";
		}
		std::cout << std::endl;
	}

	vector<int> vnResult;              //輸出結果
	vector<int> vnIndex(nGroups, 0);    //保存各組處理到數據的遊標
	vector<int> vntmp(nGroups, 0);      //用來處理分割數據並輸出合成數據的臨時空間
	std::cout << "Result" << std::endl;
	for (int j = 0; j < nNums; j++)
	{
		int nMinFlag = 0;   //最小數的位置
		for (int i = 0; i < nGroups; i++)
		{
			if (vnIndex[i] < nNums / nGroups)
				vntmp[i] = vGroup[i][vnIndex[i]];
			else
				vntmp[i] = nRandomLimit + 1;    //若該列處理完成賦值爲最大值+1
		}
		for (int i = 1; i < nGroups; i++)
		{
			if (vntmp[i] < vntmp[nMinFlag])
				nMinFlag = i;
		}
		vnResult.push_back(vGroup[nMinFlag][vnIndex[nMinFlag]]);    //輸出最大數據
		vnIndex[nMinFlag]++;
	}
	sort(vnOriginal.begin(), vnOriginal.end()); //調用系統排序函數檢測
	bool bIsSame = true;
	for (int i = 0; i < vnResult.size(); i++)
	{
		//        std::cout<<vnResult[i]<<" ";
		std::cout<<vnOriginal[i]<<" ";
		if (vnResult[i] != vnOriginal[i])
		{
			std::cout << "Something wrong!!!";
			bIsSame = false;
			break;
		}
	}
	std::cout << std::endl;
	if (bIsSame)
		std::cout << "Same to system sort." << std::endl;
}

運行結果:
在這裏插入圖片描述

下邊這個鏈接是之前寫的,對於排序不懂可以看看這篇文章。七種常見排序算法及實現

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章