【C++】自己的快速排序与二分插入排序的封装
2012-05-30 13:20
232 查看
//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"); }
上学期数据结构的一个作业。
相关文章推荐
- 数据结构图文解析之:直接插入排序及其优化(二分插入排序)解析及C++实现
- 数据结构复习:直接插入排序与二分插入排序的C++实现
- C++数据结构 排序 二分 插入 冒泡 基数 归并 直选 快排 希尔 堆排序
- C++、C#、java算法学习日记04----二分插入排序
- [Algorithms] 分治算法(二分查找, 合并排序, 插入排序, 快速排序(coming))
- python中实现二分查找,插入排序,归并排序,快速排序
- 二分插入排序
- 数据结构 - 2-路插入排序 详解 及 代码(C++)
- 笔试之排序-直接插入排序、冒泡排序、快速排序
- c++ 计蒜客挑战难题第10题寻找插入位置 二分查找
- C++插入排序之二路插入(环与非环的比较)
- Java使用二分插入排序竟然和直接插入排序速度相差不多
- C语言实现直接插入排序,冒泡排序以及二分查找(巩固理解记忆)
- 插入排序的C++代码实现
- C++模板实现直接插入排序
- c++学习连载-插入排序及其遇到的问题
- 插入,冒泡,选择,快速排序,二分查找(Java版)
- 插入排序的C++实现
- 简单插入排序(C++版)
- C++实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等