活动地址:CSDN21天学习挑战赛
正文
-
At first,我们先look一张我从某文章*的表格,来了解一下这几大算法
-
图都看了,那我也不得不提一嘴,图里面的东西了
-
算法效率
在一个算法设计完成后,还需要对算法的执行情况做一个评估。一个好的算法,可以大幅度的节省运行的资源消耗和时间。在进行评估时不需要太具体,毕竟数据量是不确定的,通常是以数据量为基准来确定一个量级,通常会使用到时间复杂度和空间复杂度这两个概念。 -
时间复杂度
通常把算法中的基本操作重复执行的频度称为算法的时间复杂度。算法中的基本操作一般是指算法中最深层循环内的语句(赋值、判断、四则运算等基础操作)。我们可以把时问频度记为T(n),它与算法中语句的执行次数成正比。其中的n被称为问题的规模,大多数情况下为输入的数据量。对于每一段代码,都可以转化为常数或与n相关的函数表达式,记做f(n)。如果我们把每一段代码的花费的时间加起来就能够得到一个刻画时间复杂度的表达式,在合并后保留量级最大的部分即可确定时间复杂度,记做O(f(n)),其中的O就是代表数量级。
常见的时间复杂度有(由低到高): O(1)、O(log2 n)、O(n)、O(n log2n)、O(n2)、o(n3)、O(2")、O(nl)。 -
空间复杂度
程序从开始执行到结束所需要的内存容量,也就是整个过程中最大需要占用多少的空间。为了评估算法本身,输入数据所占用的空间不会考虑,通常更关注算法运行时需要额外定义多少临时变量或多少存储结构。如:如果需要借助一个临时变量来进行两个元素的交换,则空间复杂度为O(1).
-
时间复杂度与空间复杂度的分类
时间复杂度
-
最坏的情况
最坏的情况莫过于,完整的遍历了整个集合,也没有找到需要找的的元素,循环执行次数与n相关,所以时间复杂度为O(n). -
最好的情况
第一次循环便找到了元素,则时间复杂度为常数级O(1); -
平常的情况
综合两种情况,顺序查找的时间复杂度为O(n),属于查找较慢的算法。
空间复杂度
算法不会改变原有的元素集合,只需要一个额外的变量控制索引变化,所以空间复杂度为常数级:O(1)。
插入排序
-
最差时间复杂度:O(n^2)
-
最优时间复杂度:O(n)
-
平均时间复杂度:O(n^2)
-
稳定性:稳定
这个插入排序有点像打扑克。
该算法的思想就和我们打扑克牌的时候一样,从牌堆里摸出来的牌顺序都是乱的,这是我们就要给扑克牌排序,按照习惯,我们摸牌的时候,会把牌自动放到左边的牌一直保持有序的位置,让手中的牌一直保持有序的状态,
具体如下图所示:
算法具体思路(抽象):
- 从第一个元素开始,该元素可以认为已经被排序
- 取出下一个元素,在已经排序的元素序列中从后向前扫描
- 如果该元素(已排序)大于新元素,将该元素移到下一位置
- 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
- 将新元素插入到该位置后
- 重复步骤2~5
源代码实现
void InsertSort(vector<int>& v)
{
int len = v.size();
cout << "排序前 " << endl;
for (int i = 0; i <= v.size() - 1; i++) {
cout << v.at(i) << " ";
}
for (int i = 1; i < len; ++i) {
int temp = v[i];
for (int j = i - 1; j >= 0; --j)
{
if (v[j] > temp)
{
v[j + 1] = v[j];
v[j] = temp;
}
else
break;
}
}
cout << endl << "排序后" << endl;
//打印整个vector
for (int i = 0; i <= v.size() - 1; i++) {
cout << v.at(i) << " ";
}
}
全部源代码:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <algorithm>
using namespace std;
void BubbleSorderly(vector<int>& v);
void SelectionSort(vector<int>& v);
vector <int> v{ 13,15,2,6,8,7,3,10,12,5,9,1,11,14,4};
//生成打乱的数据
void randperm(int Num)
{
srand((int)time(0));
vector<int> temp;
for (int i = 0; i < Num; ++i)
{
temp.push_back(i + 1);
}
random_shuffle(temp.begin(), temp.end());
for (int i = 0; i < temp.size(); i++)
{
cout << temp[i] << ",";
}
getchar();
}
void InsertSort(vector<int>& v)
{
int len = v.size();
cout << "排序前 " << endl;
for (int i = 0; i <= v.size() - 1; i++) {
cout << v.at(i) << " ";
}
for (int i = 1; i < len; ++i) {
int temp = v[i];
for (int j = i - 1; j >= 0; --j)
{
if (v[j] > temp)
{
v[j + 1] = v[j];
v[j] = temp;
}
else
break;
}
}
cout << endl << "排序后" << endl;
//打印整个vector
for (int i = 0; i <= v.size() - 1; i++) {
cout << v.at(i) << " ";
}
}
int main()
{
//randperm(15);
InsertSort(v);
getchar();
return 0;
}
//选择排序
void SelectionSort(vector<int>& v) {
int min, len = v.size();
cout << "排序前 " << endl;
for (int i = 0; i <= v.size() - 1; i++) {
cout << v.at(i) << " ";
}
for (int i = 0; i < len - 1; ++i) {
min = i;
for (int j = i + 1; j < len; ++j) {
if (v[j] < v[min]) { // 标记最小的
min = j;
}
}
if (i != min) // 交换到前面
swap(v[i], v[min]);
}
cout << endl << "排序后" << endl;
for (int i = 0; i <= v.size() - 1; i++) {
cout << v.at(i) << " ";
}
}
//冒泡排序
void BubbleSorderly(vector<int>& v)
{
//打印交换前的v向量
cout << "排序前 " << endl;
for (int i = 0; i <= v.size() - 1; i++) {
cout << v.at(i) << " ";
}
int len = v.size();
bool orderly = false;
for (int i = 0; i < len - 1 && !orderly; ++i) {
orderly = true;
for (int j = 0; j < len - 1 - i; ++j) {
if (v[j] > v[j + 1]) { // 从小到大
orderly = false; // 发生交换则仍非有序
swap(v[j], v[j + 1]);
}
}
}
cout << endl << "排序后" << endl;
//打印整个vector
for (int i = 0; i <= v.size() - 1; i++) {
cout << v.at(i) << " ";
}
getchar();
}
Test
- 输入数据 vector v{ 13,15,2,6,8,7,3,10,12,5,9,1,11,14,4};
- 结果
输入数据
vector v{ 95,10,75,66,63,24,98,89,4,59,100,8,72,99,52,5,94,57,61,56,
96,45,27,93,81,34,92,1,55,18,88,53,42,47,79,68,17,43,12,22,19,69,30,54,58,
71,87,65,36,40,48,64,6,77,39,16,97,9,74,35,29,73,15,44,51,13,82,86,85,33
,31,23,37,49,32,80,20,50,28,62,76,26,25,67,78,11,3,60,7,21,70,84,91,46,2,38,14,41,83,90};