首页 » 2020年1月

windows 下启动mysql比较麻烦,用命令行安装成mysql服务,然后启动服务来运行mysql

1.首先下载解压mysql--- https://dev.mysql.com/downloads/mysql/ ,解压后在根目录下创建mysql.ini,注意这里好多教程都没说明,路径要用双引号,否则win10报错

[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8 
[mysqld]
# 设置3306端口
port = 3306 
# 设置mysql的安装目录
basedir="E:\\baiduDown\\mysql-5.7.29-winx64"
datadir="E:\\baiduDown\\mysql-5.7.29-winx64\\data"
# 允许最大连接数
max_connections=200
# 设置mysql服务端默认字符集
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB 
# 注意这个参数,MySQL默认值导致在Windows 10 专业版上无法安装
innodb_flush_method=normal

2.管理员模式命令行执行下面的指令,注意执行的路径必须是mysql所在路径

mysqld.exe --initialize-insecure  --explicit_defaults_for_timestamp
mysqld.exe --install 

3.启动mysql服务

net start mysql

有时候算法的复杂度跟数据的排列由很大关系,这种复杂度不能简单的用一个复杂度来分析,而是由最好,最坏,平均复杂度来分析

1.如下面的,如果x在第0个位置,就是O(1),如果在第n-1个位置,就是O(n),这里就带表了最好和最坏


// n 表示数组 array 的长度,
int find(int[] array, int n, int x) {
  int i = 0;
  int pos = -1;
  for (; i < n; ++i) {
    if (array[i] == x) {
       pos = i;
       break;
    }
  }
  return pos;
}

2.最好最坏的都是极端的,大概率不会发生,那么就引入了平均(情况)时间复杂度,那么x的位置,由n+1种情况,即在0~n-1的位置,还有不在数组种

  • 我们把每种情况的时间复杂度相加,除以可能出现的情况个数,就是平均时间复杂度---即1+2+3+4+...+ n 除以n+1,平均情况时间复杂度就是:n*(n+3)/2(n+1) 分子分母,逐步忽略常量,就是O(n)

3.加权平均时间复杂度,第二步中有点问题,就是没有考虑各种情况的概率,如果x出现在某个位置的概率非常大,那么上面的计算是把所有复杂度的情况都认为是1/(n+1)。

  • 实际上我们可以考虑,x在数组中的概率是1/2,x在每个位置的概率是1/n,那么x在某个位置的概率退化为1/2n,不在数组中的概率为1/2
  • 所以加权平均值是11/2n + 21/2n +...+ n1/2n + n1/2 = (3n+1)/4
  • 第二步的算法,是理想化了,每个情况的权重都看成了1/(n+1)

4.均摊时间复杂度---摊还分析,均摊时间复杂度就是一种特殊的平均时间复杂度,即只有1/n的情况复杂度是n(这里出现的概率很规律,比如数组插入n个数后必然发生扩容,不需要概率),那么均摊下来是O(1),而不需要通过平均计算

big o是算法分析的常用手段,简单的说就是估计算法的执行时间,我们假设每行代码的时间是一样的,所以就可以理解为代码的执行次数.用n表示数据规模,f(n)表示执行次数,那么执行时间T(n) = O(f(n))表示Tn和执行次数fn成正比

1.看个简单的例子,1+ 1 + n + n ,即时间复杂度 (2n+2)*unit_time



 int cal(int n) {
   int sum = 0;//执行1次
   int i = 1;//执行1次
   for (; i <= n; ++i) {//执行n次
     sum = sum + i;//执行n次
   }
   return sum;
 }

2.再看一个例子,T(n) = O(2n2+2n+3),即O表示随着n变化时间的趋势的法则,对于函数的概念,可以理解为映射,这里大O表示次数和时间的映射

int cal(int n) {
   int sum = 0;//1
   int i = 1;//1
   int j = 1;//1
   for (; i <= n; ++i) {//n
     j = 1;//n
     for (; j <= n; ++j) {//n*n
       sum = sum +  i * j;//n*n
     }
   }
 }

3.总结+ 计算手段(下面列的都是): * 大 O 时间复杂度实际上并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,所以,也叫作渐进时间复杂度(asymptotic time complexity),简称时间复杂度

  • 计算手段1:只关注循环执行次数最多的一段代码---我们通常会忽略掉公式中的常量、低阶、系数,只需要记录一个最大阶的量级就可以了
  • 计算手段2:加法法则,如果两段代码是满足加法法则(即没有嵌套),就是次数是相加的,那么最终取最大的----如果 T1(n)=O(f(n)),T2(n)=O(g(n));那么 T(n)=T1(n)+T2(n)=max(O(f(n)), O(g(n))) =O(max(f(n), g(n))).
  • 如下满足加法法则,即n方
int cal(int n) {
   int sum_1 = 0;//sum_1 是100次
   int p = 1;
   for (; p < 100; ++p) {
     sum_1 = sum_1 + p;
   }

   int sum_2 = 0;//sum_2是n次
   int q = 1;
   for (; q < n; ++q) {
     sum_2 = sum_2 + q;
   }

   int sum_3 = 0;//sum_3是n的平方
   int i = 1;
   int j = 1;
   for (; i <= n; ++i) {
     j = 1;
     for (; j <= n; ++j) {
       sum_3 = sum_3 +  i * j;
     }
   }

   return sum_1 + sum_2 + sum_3;
 }
  • 计算手段3:如果两段代码是嵌套的,那么满足乘法法则---如果 T1(n)=O(f(n)),T2(n)=O(g(n));那么 T(n)=T1(n)T2(n)=O(f(n))O(g(n))=O(f(n)*g(n)).

    • 如下满足乘法法则,即n方
int cal(int n) {
   int ret = 0;
   int i = 1;
   for (; i < n; ++i) {
     ret = ret + f(i);//n次
   }
 }

 int f(int n) {
  int sum = 0;
  int i = 1;
  for (; i < n; ++i) {
    sum = sum + i;//n 次
  }
  return sum;
 }

4.常见的算法复杂度,复杂度分为两类:多项式量级和非多项式量级.非多项式量级只有两个:O(2^n) 和 O(n!),我们把时间复杂度为非多项式量级的算法问题叫做NP问题

  • O(1) 常数级别的都归为O(1),比如下面的代码执行了3次,也是O(1),一般情况下,只要算法中不存在循环语句、递归语句,即使有成千上万行的代码,其时间复杂度也是Ο(1)。
int i = 8;
 int j = 6;
 int sum = i + j;
  • O(logn)---对数阶算法复杂度,可以简单的理解为一个数除以k(比如k是2,即log2N)多少次可以得到1,如下面的就是

    • 对于log2N,log3N和log10N都记作logN,。因为log3n 就等于 log32 * log2n 而log32是一个常数,所以可以忽略
 i=1;
 while (i <= n)  {
   i = i * 2;
 }
  • 线性阶O(N) O(M+N)
  • 线性对数阶 O(NlogN)
  • 平方阶 O(n^2) ,O(n^3) ...O(n^k)

5.对于空间复杂度,用的最多的是O(1),O(n),O(n^2)。相对简单,不做深入