实验排序


#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <time.h>
#include <queue>
using namespace std;

typedef struct Student
{
    int id;
    int math;
    int chinese;
    int english;
    int physical;
    int sum;
}Student;
void insertSort(Student s[], int n);//直接插排序
void bubbleSort(Student s[], int n);//冒泡
void simpleSelectSort(Student s[], int n);//简单选择
void merge(Student s[], int begin1, int end1, int end2);//归并两个相邻区间
void mergeSort(Student s[], int left, int right);//归并
void radixSort(Student s[], int n);//基数

int n;
int sorttype;
string filename;

bool compare(Student a, Student b)
{
    if (a.sum > b.sum) return 1;
    if (a.sum < b.sum) return 0;
    return a.math >= b.math;
}
bool com(Student a, Student b)
{
    if (a.sum > b.sum) return 1;
    if (a.sum < b.sum) return 0;
    if (a.math > b.math) return 1;
    else return 0;
}

void sortcase()
{
    cout << "请选择排序方法" << endl;
    cout << "\t1.直接插入排序" << endl;
    cout << "\t" << endl;
    cout << "\t2.冒 泡 排 序" << endl;
    cout << "\t" << endl;
    cout << "\t3.简单选择排序" << endl;
    cout << "\t" << endl;
    cout << "\t4.归 并 排 序" << endl;
    cout << "\t" << endl;
    cout << "\t5.基 数 排 序" << endl;
    cout << "\t" << endl;
    cout << "\t6.STL sort排序" << endl;
    cout << "\t" << endl;
    cout << "\t0.退 出 程 序" << endl;
    cout << "--------------------------------" << endl;
    cin >> sorttype;
    return;
}

void filecase()
{
    cout << "请选择需要排序的文件" << endl;
    cout << "\t" << endl;
    cout << "\t1.students1.txt" << endl;
    cout << "\t2.students2.txt" << endl;
    cout << "\t3.students3.txt" << endl;
    cout << "\t4.students4.txt" << endl;
    cout << "\t5.students5.txt" << endl;
    cout << "\t6.students6.txt" << endl;
    cout << "\t7.students6正序.txt" << endl;
    cout << "\t8.students7.txt" << endl;
    cout << "\t0.返回上一个步骤" << endl;
    cout << "--------------------------------" << endl;


int choice;
    cin >> choice;
    switch (choice)
    {
    case 1:filename = "../students1.txt"; n = 10; break;
    case 2:filename = "../students2.txt"; n = 100; break;
    case 3:filename = "../students3.txt"; n = 1000; break;
    case 4:filename = "../students4.txt"; n = 10000; break;
    case 5:filename = "../students5.txt"; n = 100000; break;
    case 6:filename = "../students6.txt"; n = 1000000; break;
    case 7:filename = "../students6正序.txt"; n = 1000000; break;
    case 8:filename = "../students7.txt"; n = 10000000; break;
    case 0:filename = ""; n = 0; break;
    default:cout << "输入错误,请重新输入" << endl; filename = ""; n = 0; break;
    }
    return;
}

int maxbit(Student data[], int n)//基数排序辅助函数
{
    int maxData = data[0].sum;
    for (int i = 0; i < n; i++)
        if (maxData < data[i].sum)
            maxData = data[i].sum;
    int d = 1;
    int p = 10;
    while (maxData >= p)
    {
        maxData /= 10;
        d++;
    }
    return d;
}

int main()
{
    Student* s;
    sortcase();//选择排序类型
    while (sorttype > 0)
    {
        filecase();//选择文件
        if (filename == "")
        {
            sortcase();
            continue;
        }
        s = new Student[n];
        ifstream inFile(filename);
        for (int i = 0; i < n; i++)
        {
            inFile >> s[i].id >> s[i].math >> s[i].chinese 
                >> s[i].english >> s[i].physical;
            s[i].sum = s[i].math + s[i].chinese + s[i].english + s[i].physical;
        }
        inFile.close();
        clock_t start, end;
        start = clock();
        switch (sorttype)
        {
        case 1:insertSort(s, n); break;//直接插排序
        case 2:bubbleSort(s, n); break;//冒泡
        case 3:simpleSelectSort(s, n); break;//简单选择
        case 4:mergeSort(s, 0, n - 1); break;//归并
        case 5:radixSort(s, n); break;//基数
        case 6:sort(s, s + n, com); break;//STL sort排序
        }
        end = clock();
        cout << "排序耗时" << end - start << "毫秒" << endl;
        if (filename != "../students6正序.txt")
        {
            filename.erase(12, 4);
            filename = filename + "0.txt";
        }
        else
        {
            filename.erase(16, 4);
            filename = filename + "0.txt";
        }
        ofstream outFile(filename);
        for (int i = 0; i < n; i++)
        {
            outFile << s[i].id << "\t" << s[i].math << "\t" << s[i].chinese << "\t" 
                << s[i].english << "\t" << s[i].physical << "\t" << s[i].sum << endl;
        }
        outFile.close();
        cout << "排序结果见" << filename << endl;
        sortcase();
    }
    return 0;
}

void insertSort(Student s[], int n) 
{
    int i, j;
    Student tmp;
    for (i = 1; i < n; i++)
    {
        if (s[i].sum > s[i - 1].sum)
        {
            tmp = s[i];
            j = i - 1;
            do
            {
                s[j + 1] = s[j];
                j--;
            } while (j >= 0 && s[j].sum < tmp.sum);
            s[j + 1] = tmp;
        }
    }
}//直接插排序

void bubbleSort(Student s[], int n) 
{
    int i, j;
    bool key;
    for (i = 0; i < n - 1; i++)
    {
        key=false;
        for (j = n - 1; j > i; j--)
        {
            if (s[j].sum > s[j - 1].sum)
            {
                swap(s[j], s[j - 1]);
                key = true;
            }
        }
        if (!key)
            return;
    }
}//冒泡
void simpleSelectSort(Student s[], int n) 
{
    int i, j, k;
    for (i = 0; i < n - 1; i++)
    {
        k = i;
        for (j = i + 1; j < n; j++)
        {
            if (s[j].sum > s[k].sum)
                k = j;
        }
        if (k != i)
            swap(s[i], s[k]);
    }
}//简单选择
void merge(Student s[], int low, int mid, int high) 
{
    Student* r;
    r = (Student*)malloc((high - low + 1) * sizeof(Student));
    //申请与两区间长度之和相同的数组
    int k = 0;//k为r数组的访问头
    int i = low, j = mid + 1;//i为第一个区间的开始,j为第二个区间的开始
    while (i <= mid && j <= high)
    {
        if (compare(s[i], s[j]) == 0)
        {
            r[k] = s[j];
            j++;k++;
        }
        else
        {
            r[k] = s[i];
            i++;k++;
        }
    }
    while (i<=mid)
    {
        r[k] = s[i];
        i++; k++;
    }
    while (j <= high)
    {
        r[k] = s[j];
        j++; k++;
    }
    for (k = 0, i = low; i <= high; k++, i++)
    {
        s[i] = r[k];
    }
    free(r);
}//归并两个相邻区间
void mergeSort(Student s[], int left, int right) 
{
    int mid;
    if (left < right)
    {
        mid = (left + right) / 2;
        mergeSort(s, left, mid);
        mergeSort(s, mid + 1, right);
        merge(s, left, mid, right);
    }
}//归并
void radixSort(Student s[], int n) 
{
    int d = maxbit(s, n);
    Student* tmp = new Student[n];
    int* count = new int[10];//计数器
    int i, j, k;
    int radix = 1;
    for (i = 1; i <= d; i++)
    {
        for (j = 0; j < 10; j++)
            count[j] = 0;//每次分配前清空计数器
        for (j = 0; j < n; j++)
        {
            k = (s[j].sum / radix) % 10;//统计每个桶中的记录数
            count[k]++;
        }
        for (j = 1; j < 10; j++)
            count[j] = count[j - 1] + count[j];//将tmp中的位置依次分配给每个桶
        for (j = n - 1; j >= 0; j--)
        {
            k = (s[j].sum / radix) % 10;
            tmp[count[k] - 1] = s[j];
            count[k]--;
        }
        for (j = 0; j < n; j++)//将临时数组的内容复制到data中
            s[j] = tmp[j];
        radix = radix * 10;
    }
    delete[]tmp;
    delete[]count;
}//基数

 

posted @ 2020-10-13 16:35  XXXSANS  阅读(137)  评论(0编辑  收藏  举报