一、主要思想
- 原地重排(名次):计算数组中元素的名次,将元素交换到索引为名次的位置
- 选择排序:在数组的前size长度中,选择最大的元素交换到数组的末尾
- 冒泡排序:在数组的前size长度中,相邻元素两两相比,每次都将当前最大的元素沉到数组末尾
- 插入排序:将数组中当前有序部分的后一个元素插入前面的有序部分中
及时终止的xx排序:若当前数组有序(数组中相邻元素,后>前),则不再进行相关主要操作,直接退出
二、算法思想的图展示
说明:橙色格子代表有序;灰色格子代表无序;红色字体代表当前比较的数组元素
- 选择排序
- 冒泡排序(一次冒泡的图展示)
- 插入排序
三、实现代码
#include<iostream>
using namespace std;
template <class T>//名次排序
void rank_sorted(T a[], int n)
{
//按名次排序:将a中的元素移到相对应的名次位置中
//名次计算:某元素的名次为比它小的元素个数+它左边与它相同的元素个数
T *r = new T[n];
for (int i = 0; i < n; i++)
r[i] = 0;
for (int i = 1; i < n; i++)
{
for (int j = 0; j < i; j++)
{
if (a[j] <= a[i])
r[i]++;
else
r[j]++;
}
}
/*for (int i = 0; i < n; i++)
{
swap(a[i], a[r[i]]);
swap(r[i], r[r[i]]);
}
//swap函数定义:
temp = right;
right = left;
left = temp;
交换2个元素,移动3次
因此,如上表达的名次排序移动了6n次
*/
T *temp = new T[n];
for (int i = 0; i < n; i++)
temp[r[i]] = a[i];
for (int i = 0; i < n; i++)
a[i] = temp[i];
/*
如上表达的名次排序借助临时数组temp,移动了2n次
*/
}
template <class T>//选择排序
void select_sorted(T a[], int n)
{
//选择排序:前size个元素中选择最大的与末尾元素交换,排到最后
for (int i = n - 1; i > 1; i--)
{
//计算当前长度为i的数组,其中最大元素的索引
int max_index = 0;
for (int j = 1; j <= i; j++)
if (a[max_index] < a[j])
max_index = j;
//由swap函数的定义可知,移动次数为3(n-1)
swap(a[max_index], a[i]);
}
}
template <class T>//冒泡排序
void bubble_sorted(T a[], int n)
{
//冒泡排序:相邻元素比较,谁大谁靠后,交换元素,把最大元素移到当前最后
for (int i = n; i > 1; i--) //需要n-1次冒泡
for (int j = 0; j < i - 1; j++)
if (a[j] > a[j + 1]) //一次冒泡n-1次比较
swap(a[j], a[j + 1]);
}
template <class T>//原地重排(名次排序的不需要额外数组版)
void rank_noArray_sorted(T a[], int n)
{
//原地重排:同名次排序,但不需要额外数组空间
T *r = new T[n];
for (int i = 0; i < n; i++)
r[i] = 0;
for (int i = 1; i < n; i++)
for (int j = 0; j < i; j++)
if (a[j] <= a[i])
r[i]++;
else
r[j]++;
for (int i = 0; i < n - 1; i++)
{
if(i != r[i])
{
swap(a[i], a[r[i]]);
swap(r[i], r[r[i]]);
}
}
//如果有序,数组不用交换
//最少交换0次,最多交换2(n-1)次
}
template <class T>//及时终止的选择排序
void select_stop_sorted(T a[], int n)
{
/*
//正常选择排序:
for (int i = n - 1; i >= 1; i--)
{
int max_index = 0;
for (int j = 1; j <= i; j++)
if (a[j] > a[max_index])
max_index = j;
swap(a[max_index], a[i]);
}
*/
//及时终止的选择排序:若原数组有序,则不需要执行循环操作
bool sorted = false;//假设刚开始为无序
for (int i = n - 1; !sorted && i >= 1; i--)
{
sorted = true;//假设为有序
int max_index = 0;
for (int j = 1; j <= i; j++)
if (a[j] > a[max_index])//后一个总比前一个大为有序,否则为无序
max_index = j;
else
sorted = false;//只要出现后一个比前一个小
swap(a[max_index], a[i]);
}
}
template <class T>//及时终止的冒泡排序
void bubble_stop_sorted(T a[], int n)
{
/*
//冒泡排序:
for (int i = n; i > 1; i--)
{
for (int j = 0; j < i - 1; j++)
if (a[j] > a[j + 1])
swap(a[j], a[j + 1]);
}
*/
//及时终止的冒泡排序:有序时终止
bool swapped = true;
for (int i = n; swapped && i > 1; i--)
for (int j = 0; j < i - 1; j++)
if (a[j] < a[j + 1])
swapped = true;
else
swap(a[j], a[j + 1]);
}
template <class T>//插入排序
void insert_sorted(T a[], int n)
{
/*
for (int i = 1; i < n; i++)
{
T insert_val = a[i]; //待插入元素
for (int j = 0; j < i; j++)
{
if (a[i] < a[j])
{
for (int temp = i; temp > j; temp--)
a[temp] = a[temp - 1];
a[j] = insert_val;
break;
}
}
}
*/
//课本版代码:
for (int i = 1; i < n; i++)
{
T insert_val = a[i];
int j;
for (j = i - 1; j >= 0 && insert_val < a[j]; j--)
a[j + 1] = a[j];
a[j + 1] = insert_val;
}
}
int main(void)
{
int n;
cin >> n;
int *a = new int[n];
for (int i = 0; i < n; i++)
cin >> a[i];
//rank_sorted<int>(a, n);
//select_sorted<int>(a, n);
//bubble_sorted<int>(a, n);
//rank_noArray_sorted<int>(a, n);
//select_stop_sorted<int>(a, n);
//bubble_stop_sorted<int>(a, n);
insert_sorted<int>(a, n);
for (int i = 0; i < n; i++)
cout << a[i] << " ";
system("pause");
return 0;
}