实验内容及要求:
输入n个整数,用快速排序、堆排序与2路归并排序算法实现由小到大排序并输出排序结果。要求排序数据及排序结果用字符文件实现输入与输出。
实验目的:掌握快速排序、堆排序与2路归并排序算法。
三种排序思路简单介绍:
源程序代码:
#include<iostream>
#include<vector>
#include <fstream>
#define INPUT "input.txt"
#define OUT "out.txt"
#define N 50
using namespace std;
int Partition( vector<int>& r, int low, int high);
void Qsort( vector<int>& r, int low, int high); //递归算法实现
void QuickSort( vector<int>& r, int length); //对顺序表L做快速排序
void HAdjust(int R[], int i, int n);//从R[i]出发,向下调整算法,利用temp暂存当前结点值,直到合适的位置再放入
void HeapSort(int R[], int n);// 堆排序算法(关键字由小到大排序)
void myswap(int *p, int *q);//交换使p为归并源, q为归并目标
void merge(int p[], int s, int m, int t, int q[]);//归并p[s..m]和p[m+1..t], 结果存于q[s..t], 使q[s..t]升序
void MergeSort(int R[], int A[], int s, int t);//归并排序,递归算法
int main()
{
vector<int> r;
int r1[N] = { 0 }; int r2[N] = { 0 },A[N]{0};
fstream infile;
infile.open(INPUT, ios::in);
int j=0,k=0;
while (infile >> j)
{
r.push_back(j);
r1[k] = j;
r2[k] = j;
k++;
}
infile.close();
infile.open(OUT, ios::out);
QuickSort(r, k);
for (int i = 0; i < k; i++) infile << r[i] << " ";
infile << endl;
HeapSort(r1,k);
for (int i = 0; i < k; i++) infile << r1[i] << " ";
infile << endl;
MergeSort(r2, A,0,k);
for (int i = 1; i <= k; i++) infile << A[i] << " ";
infile.close();
return 0;
}
int Partition( vector<int>& r, int low, int high)
//以r[low]为主记录,对r[low...high]的一趟划分
{
int temp = r[low];
while (low < high) //进行一趟划分
{
while (low < high && r[high] >= temp) --high;
r[low] = r[high];
while (low < high && r[low] <= temp) ++low;
r[high] = r[low];
}
r[low] = temp; //找到主记录的位置low
return low;
}
void Qsort( vector<int>& r, int low, int high) //递归算法实现
{
if (low < high) //长度大于1
{
int loc = Partition(r, low, high); //将 r[low...high]一分为二
Qsort(r, low, loc - 1); //对低子表递归排序
Qsort(r, loc + 1, high);
}
} //对高子表递归排序
void QuickSort( vector<int>& r, int length) //对顺序表L做快速排序
{
Qsort(r, 0, r.size() - 1);
}
void HAdjust(int R[], int i, int n)//从R[i]出发,向下调整算法,利用temp暂存当前结点值,直到合适的位置再放入
{
int j;int temp=R[i];
while(i<=n/2-1) //叶子停止,非叶子继续
{
int iL=2*i+1; int iR=iL+1; //求R[i]的左/右孩子下标
j=iL; //j为R[i]要交换的结点下标
if(iR<n&&R[iR]>R[iL]) j=iR;
if(temp>R[j]) break; //根结点最大则结束调整
R[i]=R[j]; i=j;
}
R[i]=temp;
}
//堆排序算法(关键字由小到大排序)
void HeapSort(int R[], int n)
{ //初始建大根堆
int i=0;
for(i=n/2-1; i>=0; i--) HAdjust(R, i, n);
for(i=1; i<n; i++)
{
int temp=0;
temp=R[0];R[0]=R[n-i];R[n-i]=temp;
HAdjust(R, 0, n-i);
}
}
void merge(int p[], int s, int m, int t, int q[])
//p[s..m]已升序; p[m+1..t]已升序(smt)
//归并p[s..m]和p[m+1..t], 结果存于q[s..t], 使q[s..t]升序
{
int i = s, j = m + 1, k = s;
while (i <= m && j <= t)
if (p[i] <= p[j]) q[k++] = p[i++];
else q[k++] = p[j++]; //用<=是稳定的
while (i <= m) q[k++] = p[i++];
while (j <= t) q[k++] = p[j++];
}
void MergeSort(int R[], int A[], int s, int t)
//对R[s..t]进行2-路归并升序排序
//结果存于A[s..t]
{
int B[N];
if(s==t) { A[s]=R[s]; return; } //子序列长度为0
int m = (s + t) / 2;
MergeSort(R, B, s, m); //B为另一辅助数组
MergeSort(R, B, m+1, t);
merge(B, s, m, t, A);
}