【C++】自己的快速排序与二分插入排序的封装

来源:互联网 发布:美橙互联域名管理 编辑:程序博客网 时间:2024/06/05 11:13
//MySort.h
#include <stdlib.h>#ifndef MYSORT_H_INCLUDED#define MYSORT_H_INCLUDED/*函数声明 设置默认参数*/template <class T>int QuickSort_ChooseBaseNumber_First(T a[], int left, int right);template <class T>int QuickSort_ChooseBaseNumber_Middle(T a[], int left, int right);template <class T>int QuickSort_ChooseBaseNumber_Rand(T a[], int left, int right);template <class T>int QuickSort_ChooseBaseNumber_Ballance(T a[], int left, int right);template <class T>bool cmp_default(T& a, T& b);//默认比较函数,规定其返回值使得排序从小到大template <class T>void InsertionSort(T a[], int size,bool (*cmp)(T&, T&) = cmp_default);template <class T>void QuickSort(T a[], int left, int right, bool (*cmp)(T&, T&) = cmp_default, int (*getbase)(T[], int, int) = QuickSort_ChooseBaseNumber_Middle);/*函数声明 设置默认参数*/template <class T>bool cmp_default(T& a, T& b)//默认比较函数,规定其返回值使得排序从小到大{    return a < b;//若为结构体或类对象,需要重载运算符或者比较直接用其成员}template <class T>void InsertionSort(T a[], int size,bool (*cmp)(T&, T&))//二分插入排序,cmp为比较函数指针,默认为cmp_default从小到大{    T temp;    int left, right, mid;    for(int i = 0; i < size; ++i)    {        temp = a[i];        left = 0;        right = i - 1;        while(left <= right)        {            mid = (left + right) >> 1;            if( cmp(temp, a[mid]) )              right = mid - 1;            else left = mid + 1;        }        for(int j = i - 1; j >= left; --j)          a[j + 1] = a[j];        a[left] = temp;    }}/*下面快速排序*//*快排,找个基准数,把集合分成两块,左边全部比基准数小,右边全部大*/template <class T>void QuickSort(T a[], int left, int right, bool (*cmp)(T&, T&), int (*getbase)(T[], int, int)){    if(left >= right) return;    int l = left, r = right;    /*选取基准数开始*/    int base_index = getbase(a, left, right);    swap(a[left], a[base_index]);//和第一个交换    T base = a[l];    /*选取基准数结束*/    while(l < r)//开始以基准数为中进行左右分堆    {        while(!cmp(a[r], base) && l < r) --r;        if(l < r) a[l++] = a[r];        while(cmp(a[l], base) && l < r) ++l;        if(l < r) a[r--] = a[l];    }    a[l] = base;    int pos = l;    QuickSort(a, left, pos - 1, cmp);//递归左边    QuickSort(a, pos + 1, right, cmp);//递归右边}/*下面为选取基准数的几种方法*/template <class T>int QuickSort_ChooseBaseNumber_First(T a[], int left, int right)//选取基准数{    return left; /*选取第一个数*/}template <class T>int QuickSort_ChooseBaseNumber_Middle(T a[], int left, int right)//选取基准数{    return (left + right) / 2; /*选取中间*/}template <class T>int QuickSort_ChooseBaseNumber_Rand(T a[], int left, int right)//选取基准数{    return (rand() % (right - left) + left); /*选取随机数作为基准*/    //使用时尽量在最外调用处初始随机数种子    //不能在这里初始,因为调用时间间隔太小}template <class T>int QuickSort_ChooseBaseNumber_Ballance(T a[], int left, int right)//选取基准数{    /*平衡快排选取*/    if(right - left < 3) return left;//如果不足3个返回第一个    int mid = (left + right) / 2;    if(a[left] > a[mid]) swap(a[left], a[mid]);    if(a[mid] > a[right]) swap(a[mid], a[right]);    if(a[left] > a[mid]) swap(a[left], a[mid]);    return mid;}#endif // MYSORT_H_INCLUDED



 

 

//main.cpp

#include <iostream>#include <string>#include <cstdlib>#include <conio.h>#include "MySort.h"using namespace std;int menu();//菜单int input(string* str);void output(string* str, int n);void s1(string *str);//二分插入排序void s2(string *str);//快速排序bool cmpcmp(string &a,string &b) //从大到小的比较函数{    return a > b;}int main(){    system("color 0A");    string str[10000];    while(1)    {        system("cls");        int n = menu();        while(n < 1 || n > 3)        {            system("cls");            cout << "输入错误,请重新输入!" << endl;            n = menu();        }        switch(n)        {            case 1:s1(str);break;            case 2:s2(str);break;            case 3:exit(0);break;            default:break;        }    }    return 0;}int input(string* str){    int n;    cout << "请输出测试数据量n :" << endl;    cin >> n;    cout << "请输入" << n << "个字符串,空格或换行隔开:" << endl;    for(int i = 0; i < n; ++i) cin >> str[i];    return n;}void output(string* str, int n){    for(int i = 0; i < n; ++i) cout << str[i] << ' ';    cout << endl;}int menu()//菜单{    cout << "\t\t*******************************************" << endl         << "\t\t*                                         *" << endl         << "\t\t*   1.插入排序                            *" << endl         << "\t\t*   2.快速排序                            *" << endl         << "\t\t*   3.退出                                *" << endl         << "\t\t*                                         *" << endl         << "\t\t*   请按数字键进行选择                    *" << endl         << "\t\t*******************************************" << endl;    char ch = getch();    return (int)ch - '0';}void s1(string *str)//二分插入排序{    system("cls");    cout << "\t\t二分插入排序\t\t" << endl;    int n = input(str);    cout << "从小到大排序好后:" <<endl;    InsertionSort(str, n);    output(str, n);    cout <<"再从大到小排:"  << endl;    InsertionSort(str, n, cmpcmp);    output(str, n);    system("pause");}void s2(string *str)//快速排序{    system("cls");    cout << "\t\t快速排序\t\t" << endl;    int n = input(str);    cout << "从小到大排序好后:" <<endl;    QuickSort(str, 0 , n - 1);    output(str, n);    cout <<"再从大到小排:"  << endl;    QuickSort(str, 0 , n - 1, cmpcmp,QuickSort_ChooseBaseNumber_Ballance);    output(str, n);    system("pause");}


上学期数据结构的一个作业。