排序效率一览:
本章介绍了五种常见排序方法,每种方法各有利弊。
1.冒泡排序
一个指针一开始指向最后一个位置,将之前两两比较出来的最大的那个值一步步交换到这个位置上。并且加入监控是否全程没有发生交换的变量flag,可以提前终止循环,代表完成了排序。
/*冒泡排序*/
void Bubble_sort(long a[], int N)
{
int flag;//一趟冒泡是否发生交换
for (int P = N - 1; P >= 0; P--)
{
flag = 0;
for (int i = 0; i < P; i++)
{
if (a[i] > a[i + 1]) {
swap(a[i],a[i+1]);
flag = 1;
}
if (flag = 0) //全程无交换,跳出循环
break;
}
}
}
用几组特征如下的数据来检测排序算法效率(下例也一样):
数据1:只有1个元素;
数据2:11个不相同的整数,测试基本正确性;
数据3:103个随机整数;
数据4:104个随机整数;
数据5:105个随机整数;
数据6:105个顺序整数;
数据7:105个逆序整数;
数据8:105个基本有序的整数;
数据9:105个随机正整数,每个数字不超过1000。
冒泡排序效率:
2.插入排序
相当于打扑克的排序,每次新摸一张牌,就从手牌的末尾处依次比较过去并腾出一格的位置,直到找到合适的位置完成一次插入。
/*插入排序*/
void Insertion_sort(long a[], int N)
{
for (int P = 1; P < N; P++)
{
long Tmp;
int i;
Tmp = a[P];
for ( i = P; i > 0 && Tmp < a[i - 1] ; i--)
a[i] = a[i - 1];
a[i] = Tmp;
}
}
插入排序效率
3.希尔排序
升级版的插入排序,以某种特定的间隔来依次进行插入,在某种情况下有助于提高效率。
/*希尔排序,间隔插入排序*/
void Shell_sort(long a[], int N)
{
int Si, D, P, i;
long Tmp;
//使用sedgewick间隔增量
int Sedgewick[] = {
929, 505, 209, 109, 41, 19, 5, 1, 0 };
for (Si = 0; Sedgewick[Si] >= N; Si++)
;//一开始的间隔量小于排序总数
for(D = Sedgewick[Si]; D>0 ; D = Sedgewick[++Si])
for (P = D; P < N; P++)
{
Tmp = a[P];
for (i = P; i >= D && Tmp < a[i - D]; i -= D) //注意是i-D而不是i-1 并且是i>D而不是i>0
a[i] = a[i - D];
a[i] = Tmp;
}
}
4.堆排序
(若你要排从小到大序列)先构建一个最大堆(在数组中就是一个个整理子树,整理到根节点为止),然后将堆顶最大元素和当前堆的最后一个元素交换位置。最后将最后一个元素整个踢出堆(也就是将堆的规模缩小一位)。
/*堆排序*/
void Swap(long *a, long *b)
{
long t = *a;
*a = *b;
*b = t;
}
void PerDown(long a[], int p, int N)//向下过滤函数
{
int Parent, Child;
long X;
X = a[p]; //取出根节点的值
for (Parent = p; (Parent * 2 + 1) < N; Parent = Child)
{
Child = Parent * 2 + 1;//因为从0开始的,所以左儿子要加一
if ((Child != N - 1) && (a[Child] < a[Child + 1]))
Child++;//child指向左右儿子中较大者
if (X >= a[Child])
break; //若根节点大于此时的最大的儿子,则找到合适位置
else
a[Parent] = a[Child];
}
a[Parent] = X;
}
void HeapSort(long a[],int N)
{
int i;
/*从0开始的树,所以最后一个父节点是N/2-1,把10带进去很好理解。
建树的时候所有点都是乱的,所以每个子树都要向下过滤调整,
但交换后就不一样了,只有堆顶的元素是乱的,所以不用写循环了*/
for (i = N / 2 - 1; i >= 0; i--)
PerDown(a, i ,N );//向下过滤,整理树
for (i = N - 1; i > 0; i--)//每循环一次缩小一次堆的规模
{
Swap(&a[0], &a[i]);//交换堆顶和最后一个元素
PerDown(a, 0, i);
}
c++背诵版:
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
int n = nums.size();
HeapSort(nums