本篇博文,旨在介绍洗牌算法;并用C++实现了洗牌算法
洗牌算法
我们都多多少少学过几种排序,常见的几种排序大类有插入排序,希尔排序,选择排序,交换排序
然而,洗牌算法的目的是将有序的数组进行打乱
一般的洗牌算法
1、利用一个队列
2、每次从数组中,随机找到一个数;
若该数没有被选择过,那么就将它放入队列中;
如果被选择过,就重新随机
毋庸置疑,这个算法是可以满足洗牌的要求的
然而呢,让我们看一下该算法时间复杂度
每次选择一个数,可能存在已经选择过的情况
所以该算法的时间复杂度是O(N* N)
并且又多用到了一个队列,空间复杂度也不是很好
更优的洗牌算法
该算法类似于插入排序
从数组的最后一个数(下标为i)开始,进行随机取余(除数为i+1,确保下标不过界)
将得到的下标对应的元素和最后一个数交换
将最后一个数不在视为数组中的元素,继续循环
直到只剩下第一个元素为止
洗牌算法的代码实现
#pragma once
#include<iostream>
using namespace std;
#include<time.h>
//打印函数
void Print(int* a, size_t n)
{
for (size_t i = 0; i<n; ++i)
cout << a[i] << " ";
cout << endl;
}
//进行洗牌
void Shuffe(int* a, int n)
{
for (int i = n - 1; i > 0; --i)
{
srand((unsigned)time(NULL));//不加此语句的话,每次随机的数会不变
swap(a[i], a[rand() % (i + 1)]);
}
}
//测试洗牌算法
void TestShuffe()
{
int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Shuffe(a, sizeof(a) / sizeof(a[0]));
Print(a, sizeof(a) / sizeof(a[0]));
}