การเรียงลำดับภายนอก เป็นหมวดหมู่ของอัลกอริธึมการเรียงลำดับที่สามารถจัดเรียงข้อมูลจำนวนมากได้ การเรียงลำดับประเภทนี้ใช้กับชุดข้อมูลที่ได้รับหน่วยความจำขนาดใหญ่ซึ่งไม่สามารถเก็บไว้ในหน่วยความจำหลัก (RAM) และจัดเก็บไว้ในหน่วยความจำรอง ( ฮาร์ดดิสก์)
แนวคิดในการจัดเรียงที่ใช้ในการจัดเรียงภายนอกค่อนข้างคล้ายกับ การจัดเรียงแบบผสาน นอกจากนี้ยังมีสองขั้นตอนเช่นในการเรียงลำดับ
ใน ระยะการจัดเรียง ชุดข้อมูลขนาดหน่วยความจำขนาดเล็กจะถูกจัดเรียง จากนั้นใน เฟสผสาน สิ่งเหล่านี้จะรวมกันเป็นชุดข้อมูลเดียว
การเรียงลำดับภายนอก
สำหรับชุดข้อมูลขนาดใหญ่ที่ไม่สามารถประมวลผลได้ในครั้งเดียว ข้อมูลถูกแบ่งออกเป็นชิ้นเล็ก ๆ ชิ้นส่วนเหล่านี้จะถูกจัดเรียงและจัดเก็บไว้ในไฟล์ข้อมูล
อัลกอริทึม:
ขั้นตอนที่ 1: อ่านข้อมูลอินพุตจากไฟล์และป้อนเป็นชุดข้อมูลขนาดหน่วยความจำ
ขั้นตอนที่ 2: สำหรับชุดข้อมูลขนาดเล็กแต่ละชุด ให้จัดเรียงแต่ละชุดโดยใช้การจัดเรียงแบบผสาน
ขั้นตอนที่ 3: จัดเก็บข้อมูลที่เรียงลำดับลงในไฟล์
ขั้นตอนที่ 4: รวมไฟล์ข้อมูลที่จัดเรียงไว้แต่ละไฟล์
โปรแกรมแสดงการทำงานของอัลกอริทึม:
ตัวอย่าง
#include <bits/stdc++.h>
using namespace std;
struct MinHeapNode {
int element;
int i;
};
void swap(MinHeapNode* x, MinHeapNode* y);
class MinHeap {
MinHeapNode* harr;
int heap_size;
public:
MinHeap(MinHeapNode a[], int size);
void MinHeapify(int);
int left(int i) {
return (2 * i + 1);
}
int right(int i) {
return (2 * i + 2);
}
MinHeapNode getMin() {
return harr[0];
}
void replaceMin(MinHeapNode x) {
harr[0] = x;
MinHeapify(0);
}
};
MinHeap::MinHeap(MinHeapNode a[], int size) {
heap_size = size;
harr = a;
int i = (heap_size - 1) / 2;
while (i >= 0) {
MinHeapify(i);
i--;
}
}
void MinHeap::MinHeapify(int i) {
int l = left(i);
int r = right(i);
int smallest = i;
if (l < heap_size && harr[l].element < harr[i].element)
smallest = l;
if (r < heap_size && harr[r].element < harr[smallest].element)
smallest = r;
if (smallest != i) {
swap(&harr[i], &harr[smallest]);
MinHeapify(smallest);
}
}
void swap(MinHeapNode* x, MinHeapNode* y)
{
MinHeapNode temp = *x;
*x = *y;
*y = temp;
}
void merge(int arr[], int l, int m, int r)
{
int i, j, k;
int n1 = m - l + 1;
int n2 = r - m;
int L[n1], R[n2];
for (i = 0; i < n1; i++)
L[i] = arr[l + i];
for (j = 0; j < n2; j++)
R[j] = arr[m + 1 + j];
i = 0;
j = 0;
k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j])
arr[k++] = L[i++];
else
arr[k++] = R[j++];
}
while (i < n1)
arr[k++] = L[i++];
while (j < n2)
arr[k++] = R[j++];
}
void mergeSort(int arr[], int l, int r) {
if (l < r) {
int m = l + (r - l) / 2;
mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);
merge(arr, l, m, r);
}
}
FILE* openFile(char* fileName, char* mode)
{
FILE* fp = fopen(fileName, mode);
if (fp == NULL) {
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
return fp;
}
void mergeData(char* opFile, int n, int k) {
FILE* in[k];
for (int i = 0; i < k; i++) {
char fileName[2];
snprintf(fileName, sizeof(fileName), "%d", i);
in[i] = openFile(fileName, "r");
}
FILE* out = openFile(opFile, "w");
MinHeapNode* harr = new MinHeapNode[k];
int i;
for (i = 0; i < k; i++) {
if (fscanf(in[i], "%d ", &harr[i].element) != 1)
break;
harr[i].i = i;
}
MinHeap hp(harr, i);
int count = 0;
while (count != i) {
MinHeapNode root = hp.getMin();
fprintf(out, "%d ", root.element);
if (fscanf(in[root.i], "%d ",
&root.element)
!= 1) {
root.element = INT_MAX;
count++;
}
hp.replaceMin(root);
}
for (int i = 0; i < k; i++)
fclose(in[i]);
fclose(out);
}
void initialiseData( char* ipFile, int memory, int num_ways) {
FILE* in = openFile(ipFile, "r");
FILE* out[num_ways];
char fileName[2];
for (int i = 0; i < num_ways; i++) {
snprintf(fileName, sizeof(fileName), "%d", i);
out[i] = openFile(fileName, "w");
}
int* arr = (int*)malloc( memory * sizeof(int));
bool more_input = true;
int next_opFile = 0;
int i;
while (more_input) {
for (i = 0; i < memory; i++) {
if (fscanf(in, "%d ", &arr[i]) != 1) {
more_input = false;
break;
}
}
mergeSort(arr, 0, i - 1);
for (int j = 0; j < i; j++)
fprintf(out[next_opFile], "%d ", arr[j]);
next_opFile++;
}
for (int i = 0; i < num_ways; i++)
fclose(out[i]);
fclose(in);
}
void externalSort( char* ipFile, char* opFile, int num_ways, int memory) {
initialiseData(ipFile, memory, num_ways);
mergeData(opFile, memory, num_ways);
}
int main() {
int num_ways = 10;
int memory = 1000;
char ipFile[] = "inputFile.txt";
char opFile[] = "outputFile.txt";
FILE* in = openFile(ipFile, "w");
srand(time(NULL));
for (int i = 0; i < num_ways * memory; i++)
fprintf(in, "%d ", rand());
fclose(in);
externalSort(ipFile, opFile, num_ways, memory);
return 0;
} ข้อมูลที่ป้อนเข้าเป็นไฟล์ข้อมูลที่ไม่เรียงลำดับในขณะที่เอาต์พุตจะมีอาร์เรย์ที่จัดเรียง