面向对象方式实现六种排序算法

c++以面向对象方式实现六种排序算法

六种排序算法

      1、选择排序
      2、冒泡排序
      3、插入排序
      4、基数排序
      5、快速排序
      6、合并排序
      7、及时终止的选择排序
      8、及时终止的冒泡排序
      当然还存在计数排序,堆排序等排序方法,但以后只会以功能函数的形式出现。
      各种排序算法原理在代码中以注释给出

代码

/*
以面向对象的思维实现一个排序算法的总结 
排序算法:
1、选择排序
2、冒泡排序
3、插入排序
4、基数排序
5、快速排序
6、归并排序 
*/

#include <iostream>
using namespace std;

template <class T>
void swapAB(T & a, T & b){
	T temp = a;
	a = b;
	b = temp;
}

template <class T>
class sort{
	public:
		sort(int num = 3);
		sort(T *array, int len);
		sort(const sort<T> &); 
		~sort(){
			delete [] arr;
		} 
		int getSize();
		void selectionSort();	//选择排序 
		void bubbleSort();		//冒泡排序 
		void insertionSort();	//插入排序 
		void radixSort();		//基数排序 
		void quickSort(int low, int high);		//快速排序 
		void mergeSort();		//归并排序
		void mergeSort_merge(int first, int mid, int last, T temp[]);
		void mergeSort_sort(int first, int last, T temp[]);
		
		void selectionSortB();	//及时终止的选择排序
		void bubbleSortB(); 	//及时终止的冒泡排序
		 
		void output();
		 
	private:
		T *arr;		//存储元素的数组 
		int size; 	//元素个数 
};
//构造函数 
template <class T>
sort<T>::sort(int num){
	if(num <= 0){
		cout <<"the num of array must > 0"<<endl;
		throw "the num of array must > 0";
	}
	size = num;
	arr = new T[size];
}
//构造函数
template <class T>
sort<T>::sort(T *array, int len){
	if(len <= 0){
		cout <<"the length of array must > 0"<<endl;
		throw "the length of array must > 0";
	}
	size = len;
	arr = new T[size];
	for(int i=0; i<size; i++){
		arr[i] = array[i];
	} 
} 
//复制构造函数 
template <class T>
sort<T>::sort(const sort<T> & theArr){
	size = theArr.size;
	arr = new T[size];
	for(int i=0; i<size; i++){
		arr[i] = theArr[i];
	}
}
//获取元素个数
template <class T>
int sort<T>::getSize(){
	return size;
} 

//选择排序
/*
1. 每次选择一个最大的数放到最后 
2. 内层循环找出在前i个元素[0::i-1]中最大的那个数的索引
   外层循环 每次 将内层循环找出的数 放到第i-1个位置,然后 i-- 
*/
template <class T>
void sort<T>::selectionSort(){ 			
	for(int i=size; i>1; i--){
		int max_index = 0;
		for(int j=1; j<i; j++){ 	//前i个数字是无序的 
			if(arr[max_index] < arr[j]){
				max_index = j;
			}
		}
		swapAB(arr[i-1], arr[max_index]); //将最大数 与 最后一个位置的数字互换 
	}
} 

//冒泡排序
/*
1. 比较相邻两个元素,如果前一个比后一个大,则swap
2. 设有n个元素,则索引为[0::n-1],
    则需进行n-1轮比较,每轮都确定一个最大的放到最后 
	则第i轮时,有i个元素以确定即arr[n-1-i,n-1]
	有n-1-i个元素还没排序,即arr[0, n-1-i-1] 
*/
template <class T>
void sort<T>::bubbleSort(){
	for(int i=size; i>1; i--){
		for(int j=0; j<i-1; j++){
			if(arr[j] > arr[j+1]){
				swapAB(arr[j], arr[j+1]);
			}
		}
	}	
} 

//插入排序
/*
1. 将元素从头开始不断的向自己所在的数组空间插入
2. 当只有一个元素时,不用排序
    多于1个元素时 ,从第2个元素开始向已有数组里面插入,
	插入之前,要将大于第i个元素之前,且数值大于arr[i]的元素向后移 
*/
template <class T>
void sort<T>::insertionSort(){
	for(int i=1; i<size; i++){
		T temp = arr[i];
		int j;
		for(j=i-1; j>=0 && temp < arr[j]; j--){
			arr[j+1] = arr[j];
		}
		arr[j+1] = temp;
	} 
}

//基数排序
/*
1. 利用了桶的原理,从低位开始比起,不断放入桶再从从中依次拿出,比至最高位,拿出的是有序的 
2.  首先要确定最高位对应的数字,即需要比几轮 
*/
template <class T>
void sort<T>::radixSort(){
	//1 确定最大的位数  d 
	int d = 1; 			//保存最大的位数 
	int p = 10;
	for(int i=0; i<size; i++){
		while(arr[i] >= p){
			d++;
			p *= 10; 
		}
	} 
	//2 分配 收集 
	T *tmp = new T[size];
	int *count = new int[10];	//计数器 , 0-9 10个桶 
	int i, j, k;
	int radix = 1;
	for(i = 1; i <= d; i++){	//共分配收集 d 次 
		for(j=0; j<10; j++){
			count[j] = 0;		//每次分配前清空计数器(桶) 
		}
		for(j=0; j<size; j++){
			k = (arr[j] / radix) % 10;	//将每个数分配到不同的桶中
			count[k]++;					//对应桶中数字的个数+1 
		}
		for(j=1; j<10; j++){
			count[j] = count[j-1] + count[j]; //a, a+b, a+b+c, ...., size 
		} 
		for(j = size-1; j>=0; j--){	 //收集 从后向前是为了 将每个桶 上端的数 保持在相对的后面 
			k = (arr[j] / radix) % 10;		//确定arr[j]属于那个桶 
            tmp[count[k] - 1] = arr[j];		//上端的位于后面 
            count[k]--;						
		}
		for(j = 0; j < size; j++) //将临时数组的内容复制到data中
            arr[j] = tmp[j];
        radix = radix * 10;		//进行下一轮分配收集 
	} 
	delete[] tmp;
	delete[] count;
} 

//快速排序
/*
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。  
*/
template <class T>
void sort<T>::quickSort(int low, int high){
	if(low < high){
		int i = low, j = high;
		T key = arr[low];
		while(i < j){
			while(i<j && arr[j] >= key){	//从右向左, 找小于key的 
				j--;
			}
			if(i < j){
				arr[i] = arr[j];
				i++; 
			}
			while(i<j && arr[i] < key){
				i++;
			}
			if(i < j){
				arr[j] = arr[i];
				j--;
			}
		}
		arr[i] = key;
		quickSort(low, j-1);
		quickSort(j+1, high); 	
	}
}

//归并排序
//将有序数列a[first...mid]和a[mid...last]合并。
template <class T>
void sort<T>::mergeSort_merge(int first, int mid, int last, T temp[]){
	int i = first, j = mid+1;
	int m = mid, n = last;
	int k = 0;
	
	while(i <= m && j <= n){
		if(arr[i] <= arr[j]){
			temp[k] = arr[i];
			k++;
			i++; 
		}
		else{
			temp[k] = arr[j];
			k++;
			j++;
		}
	}
	while(i <= m){
		temp[k] = arr[i];
		k++;
		i++;
	}
	while(j <= n){
		temp[k] = arr[j];
		k++;
		j++;
	}
	//重新写回
	for(i = 0; i<k; i++){
		arr[first+i] = temp[i];
	}	
}
//当每块数据都只有一个数据时,可用mergeSort_merge()合并 
template <class T>
void sort<T>::mergeSort_sort(int first, int last, T temp[]){
	if(first < last){
		int mid = (first+last) / 2;
		mergeSort_sort(first, mid, temp);
		mergeSort_sort(mid+1, last, temp);
		mergeSort_merge(first, mid, last, temp);
	}
}
template <class T>
void sort<T>::mergeSort(){
	T *p = new T[size];
	mergeSort_sort(0, size-1, p);
	delete [] p;
} 

//及时终止的选择排序
template <class T>
void sort<T>::selectionSortB(){
	bool sorted = false;
	
	for(int i=size; !sorted && i>0; i--){
		int max_index = 0;
		sorted = true;
		for(int j=1; j<i; j++){
			if(arr[max_index] <= arr[j]){
				max_index = j;
			}
			else{
				sorted = false;
			}
		}
		swapAB(arr[max_index], arr[i-1]);
	}
}
 
//及时终止的冒泡排序
template <class T>
void sort<T>::bubbleSortB(){
	bool sorted = false;
	for(int i=size; !sorted && i>1; i--){
		sorted = true;
		for(int j=0; j<i-1; j++){
			if(arr[j] > arr[j+1]){
				swapAB(arr[j], arr[j+1]);
				sorted = false;
			}
		}
	}
} 
//输出
template <class T>
void sort<T>::output(){
	for(int i=0; i<size; i++){
		cout <<arr[i]<<" ";
	}
	cout <<endl;
} 

//测试
int main(){
	int array[4] = {4, 3, 2, 1};
	int len = sizeof(array) / sizeof(array[0]);
	
	/*
	//2.测试冒泡排序 
	sort<int> *s1 = new sort<int>(array, len);
	s1->output();
	s1->insertionSort(); 
	s1->output(); 
	*/
	
	bool finish = false;
	while(!finish){
		sort<int> *s1 = new sort<int>(array, len);
		s1->output();
		
		int function = 0;
		cout <<"*************************************"<<endl;
		cout <<"请选择排序方式:"<<endl;
		cout <<"\t 1: 选择排序"<<endl;
		cout <<"\t 2: 冒泡排序"<<endl;
		cout <<"\t 3: 插入排序"<<endl;
		cout <<"\t 4: 基数排序"<<endl;
		cout <<"\t 5: 快速排序"<<endl;
		cout <<"\t 6: 归并排序"<<endl;
		cout <<"\t 7: 及时终止的选择排序"<<endl;
		cout <<"\t 8: 及时终止的冒泡排序"<<endl; 
		cout <<"\t 9: 退出"<<endl; 
		cin >>function;
		switch(function){
			case 1:
				s1->selectionSort();
				break;
			case 2:
				s1->bubbleSort();
				break;
			case 3:
				s1->insertionSort();
				break;
			case 4:
				s1->radixSort();
				break; 
			case 5:
				s1->quickSort(0, s1->getSize()-1);
				break; 
			case 6: 
				s1->mergeSort();
				break; 
			case 7:
				s1->selectionSortB();
				break;
			case 8:
				s1->bubbleSortB();
				break;
			case 9:
				finish = true;
				break;
			default:
				cout <<"输入错误,请重新输入"<<endl; 
		}
		if(!finish){
			cout <<"排序后输出:"; 
			s1->output();
			cout <<endl;
		}
		delete s1;
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值