实验2 排序算法
要求
- 不得使用与实验相关的STL
- 需使用类模版(
template<class T>
) - 需定义排序类,封装各排序方法
- 排序数据需使用动态数组存储
- 排序类需提供以下操作:名次排序、及时终止的选择排序、及时终止的冒泡排序、插入排序
描述
用任意一种排序方式给出n个整数按升序排序后的结果
格式
输入
输入的第一行是一个整数 n(1<=n<=1000),表示需排序的数的个数。接下来一行是 n 个整数,数的范围是 0 到 1000,每两个相邻数据间用一个空格分隔。
输出
一行排好序的序列
思路与探讨
整体思路:定义排序类,对各排序进行封装,而后分别对各个排序进行说明。
名次排序
名次排序一句话总结
先计算每个元素的具体位置,再将其移动到相应位置
思路
-
给数组a[n]中的元素进行名次的计算。
int assist[100];//存储对应索引的名次 for(int i = 0;i < n;i++) {//先全部初始化 assist[i] = 0; } for(int i = 1;i < n;i++) {//给每个元素按大小标定名次 for(int j = 0;j < i;j++) { if(array[j] <= array[i]) assist[i]++; else assist[j]++; } }
例:a[]={2,1,5,7,6},计算完名次之后会出现r[]={2,1,3,5,4},每一个r中元素代表的是其在a数组中对应元素所排的名次。
-
名次排定后,利用一个附加数组进行辅助排序
T *new_array = new T [n];//创建附加数组 for (int i = 0;i < n;i++) { //利用辅助数组,按照名次将array[i]暂时贴到新开辟的new_array[]中 //这一句的逻辑是assist[i]的值是array[i]本该在的索引,通过以下语句让其归位。 new_array[assist[i]] = array[i]; } for (int j = 0;j < n;j++) { //将数组array重新进行赋值操作 array[j] = new_array[j]; } delete []new_array;
及时终止的选择排序
选择排序一句话总结
每次寻找出[1,size]中的最大元并将其置于[size-1],每次循环 size--
。
思路——终止条件的设置
-
开一个用于终止判断的bool变量judge_1,在进入遍历循环前,将judge_1置为false。
-
进入循环后,从左往右若都符合大的在右边,小的在左边,即一直都符合
if(array[Max] <= array[i]) Max = i;
那就没有机会再把judge_1置回为true。即一直走不到
else judge_1 = true;
这一句 -
因此外圈循环判断语句
for(int size = n;judge_1 && (size > 1);size--)
会将其阻挡在外,即排好了就及时终止- 外圈循环——控制终止,size–,由外圈循环进入遍历循环
- 遍历循环——在每一个size下都来一次,找最大元,置于当前最右处
及时终止的冒泡排序
冒泡排序一句话总结
每次冒泡依次比较相邻元素,并将相邻元素的较大元向右移动,每一次会把最大的换至最右,并重复这一操作。
思路——终止条件的设置
-
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
if(array[i] > array[i+1]) { Sort<T>::swap(array[i],array[i+1]); judge_2 = true; }
-
对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
-
针对所有的元素重复以上的步骤,除了最后一个。因此每次
size--
。 -
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
- 也是开一个bool变量judge_2,遍历循环前置为false,若还需要交换,就会运行上述代码,将其置true,继续排序。
插入排序
插入排序一句话总结
把每一个元素依次作为插入元素 ,找到合适的位置插入,维护一个有序列。
思路
- 采用升序插入排序,即先把数组的第一个元素视为已排序元素
- 后将第二个元素拿去插入,若比第一个小,就插到第一个前,反之插到其后
- 再把第三个元素拿去插入,和前两个元素都比较,找到合适的位置。
- 以此类推。
若已看懂思路,试着自己写~
实现代码(全)
#include<iostream>
using namespace std;
//定义排序类,对各排序进行封装
template<class T>
class Sort{
public:
Sort(int n);//构造函数
~Sort(){};//析构函数
void swap(T &x,T &y);//交换函数,排序过程必备
void rankSort(T *array,int n);//名次排序
void selectionSort(T *array,int n);//及时终止的选择排序
void bubbleSort(T *array,int n);//及时终止的冒泡函数
void insertSort(T *array,int n);//插入排序
private:
int n_begin;//构造函数的初始化值
};
//构造函数初始化
template <class T>
Sort<T>::Sort(int n)
{
if (n < 0)
n_begin = 0;
else
n_begin = n;
}
//交换函数
template<class T>
void Sort<T>::swap(T &x,T &y)
{
int temp;
temp = x;
x = y;
y = temp;
}
//名次排序
template<class T>
void Sort<T>::rankSort(T *array,int n)
{
T *new_array = new T [n];//创建附加数组
int assist[100];
for(int i = 0;i < n;i++)
{
assist[i] = 0;
}
for(int i = 1;i < n;i++)
{
for(int j = 0;j < i;j++)
{
if(array[j] <= array[i])
assist[i]++;
else
assist[j]++;
}
}
for (int i = 0;i < n;i++)
{
//利用辅助数组,按照名次将array[i]暂时贴到新开辟的new_array[]中
new_array[assist[i]] = array[i];
}
for (int j = 0;j < n;j++)
{
array[j] = new_array[j];//将数组array重新进行赋值操作
}
delete []new_array;
}
//及时终止的选择排序
template<class T>
void Sort<T>::selectionSort(T *array,int n)
{
bool judge_1 = true;
for(int size = n;judge_1 && (size > 1);size--)//终止条件
{
int Max = 0;
judge_1 = false;
for(int i = 1;i < size;i++)
{
if(array[Max] <= array[i]) Max = i;
else judge_1 = true;
}
Sort<T>::swap(array[Max],array[size-1]);//每一次挑出最大的放到右边去
}
}
//及时终止的冒泡排序
template<class T>
void Sort<T>::bubbleSort(T *array,int n)
{
bool judge_2 = true;
for (int size = n;judge_2 && (size > 1);size--)
{
bool judge_2 = false;
for(int i = 0;i < n-1;i++)//把array[0:n-1]中最大元素移到右边
{
if(array[i] > array[i+1])
{
Sort<T>::swap(array[i],array[i+1]);
judge_2 = true;
}
}
}
}
//插入排序
template<class T>
void Sort<T>::insertSort(T *array,int n)
{
for (int i = 1;i < n;i++)
{
T x = array[i];//把每一个元素依次作为插入元素
int j;
for(j = i-1;j >= 0 && x < array[j];j--)
{
array[j + 1] = array[j];
}
array[j + 1] = x;
}
}
int main()
{
int a[100];
int n;
Sort<int> s(n);
cin >> n;
for(int i = 0;i < n;i++)
{
cin >> a[i];
}
s.rankSort(a,n);
for(int j = 0;j < n;j++)
{
cout << a[j] << " ";
}
return 0;
}