算法复杂度计算方法 , 排序算法和数据结构简介

目录

一 时间复杂度和空间复杂度

1.1时间复杂度

1.2空间复杂度

二 数据结构

2.1逻辑结构

2.2 存储结构

2.3 数据结构-二叉树

3 算法

3.1排序

3.2 查找 

3.3斐波那契数列


一 时间复杂度和空间复杂度

1.1时间复杂度

一个算法的时间复杂度反映了程序运行程序开始到结束所需要的时间。把算法中基本操作重复执行的次数 (频度) 作为算法的时间复杂度

  • 没有循环语句记作O(1),也称为常数阶。
  • 只有一重循环,则算法的基本操作的执行频度与问题规模n呈线性增大关系,记作O(n),也叫线性阶

常见的时间复杂度有:

  • O(1): Constant Complexity: Constant 常数复杂度
  • O(log n): Logarithmic Complexity: 对数复杂度
  • O(n): Linear Complexity: 线性时间复杂度
  • O(n^2): N square Complexity 平⽅方
  • O(n^3): N square Complexity ⽴立⽅方
  • O(2^n): Exponential Growth 指数
  • O(n!): Factorial 阶乘

计算demo:

function aFunc(n) {
    for(int i = 0; i < n; i++) {         // 循环次数为 n
        printf("Hello, World!\n");      // 循环体时间复杂度为 O(1)
    }
}
// 上面时间复杂度为 O(n × 1),即 O(n)。

function aFunc(n) {
    for(int i = 0; i < n; i++) {         // 循环次数为 n
        for(int j = 0; j < n; j++) {       // 循环次数为 n
            printf("Hello, World!\n");      // 循环体时间复杂度为 O(1)
        }
    }
}
// 上面时间复杂度为 O(n × n × 1),即 O(n^2)。

进阶demo

function aFunc(int n) {
    for (int i = 2; i < n; i++) {
        i *= 2;
        printf("%i\n", i);
    }
}
// 假设循环次数为 t,则循环条件满足 2^t < n。
// 可以得出,执行次数t = log(2)(n),
// 即 T(n) = log(2)(n),可见时间复杂度为 O(log(2)(n)),即 O(log n)。



function aFunc(int n) {
    if (n <= 1) {
        return 1;
    } else {
        return aFunc(n - 1) + aFunc(n - 2);
    }
}
// 显然运行次数,T(0) = T(1) = 1,同时 T(n) = T(n - 1) + T(n - 2) + 1,这里的 1 是其中的加法算一次执行。
// 显然 T(n) = T(n - 1) + T(n - 2) 是一个斐波那契数列,通过归纳证明法可以证明,当 n >= 1 时 T(n) < (5/3)^n,同时当 n > 4 时 T(n) >= (3/2)^n。
// 所以该方法的时间复杂度可以表示为 O((5/3)^n),简化后为 O(2^n)。

1.2空间复杂度

一个程序的空间复杂度是指运行完一个程序所需内存的大小。利用程序的空间复杂度, 可以对程序的运行所需要的内存多少有个预先估计

二 数据结构

数据结构即数据元素相互之间存在的一种和多种特定的关系集合

2.1逻辑结构

逻辑结构就是数据之间的关系, 大概统一分成两种:线性结构,非线性结构

线性结构:是一个有序数据元素的集合。其中数据元素之间的关系是一对一的关系,即除了第一个和最后一个元素之外,其他元素都是首尾相接的。

常用的线性结构有:栈,队列,链表,线性表。

非线性结构 :各个数据元素不再保持在一个线性序列中,每个数据元素可能与零个或者多个其他数据元素发生联系。

常见的非线性结构:二维数据,树等。

2.2 存储结构

存储结构是逻辑结构用计算机语言的实现。常见的存储结构有顺序存储,链式存储,索引存储以及散列存储。

列如:

  • 数组在内存中的位置是连续的,它就属于顺序存储;
  • 链表是主动建立数据间的关联关系的,在内存中却不一定是连续的,属于链式存储;
  • 顺序和逻辑上都不存在顺序关系,但是你可以通过一定的方式去访问它的哈希表,属于散列存储;

2.3 数据结构-二叉树

二叉树是一种典型的树状结构。如他的名字所描述的那样,二叉树是每个节点最多有两个子树的树结构,通常被称为’左子树‘和’右子树‘。

常用的二叉树的遍历方式:前序遍历、中序遍历、后序遍历、层序遍历
(1)前序遍历:根、左、右;
(2)中序遍历:左、根、右;
(3)后续遍历:左、右、根;
(4)层序遍历:从上到下,同层节点从左到右。

3 算法

3.1排序

  • 快速排序

选择一个目标值,比目标值小的放左边,比目标值大的放右边,目标值的位置已排好,将左右两侧再进行快排

  • 时间复杂度:平均O(nlogn),最坏O(n2),实际上大多数情况下小于O(nlogn)
  • 空间复杂度:O(logn)(递归调用消耗
  • 不稳定
 function quickSort(arr){
            if(arr.length<1){
                return arr;
            }
            var pivotIndex=Math.floor(arr.length/2);//找到那个基准数
            var pivot=arr.splice(pivotIndex,1)[0]; //取出基准数,并去除,splice返回值为数组。
            var left=[]; 
            var right=[];
            for(var i=0;i<arr.length;i++){
                if(arr[i]<pivot){
                    left.push(arr[i]);
                }else{
                    right.push(arr[i]);
                }
            }
            return quickSort(left).concat([pivot],quickSort(right)); //加入基准数
        }
        let arr=[2,1,5,8,3,7,4,6,9];
        console.log(quickSort(arr)); //[1, 2, 3, 4, 5, 6, 7, 8, 9]
  •  选择排序

每次排序取一个最大或最小的数字放到前面的有序序列中。

  • 时间复杂度:O(n2)
  • 空间复杂度:  O(1)
  • 稳定

function selsetSort(arr){
	var len = arr.length;
	var index;
	for(let i=0;i<len-1;i++){
		index=i;
		for(let j=i+1;j<len;j++){
			if(arr[index]>arr[j]){//寻找最小值
				index=j;//保存最小值的索引
			}
		}
		if(index!=i){
		var temp =arr[i];
		arr[i]=arr[index];
		arr[index]=temp;
	}
	}
	return arr;
}

3.2 查找 

  • 二分查找
    function binarySearch(data, dest) {
      var end = data.length - 1,
        start = 0;
      while (start <= end) {
        var m = Math.floor((end + start) / 2);
        if (data[m] == dest) {
          return m;
        }
        if (dest > data[m]) {
          start = m + 1;
        } else {
          end = m - 1;
        }
      }
      return false;
    }
    var arr = [-34, 1, 3, 4, 5, 8, 34, 45, 65, 87];
    console.log(binarySearch(arr, 4));

3.3斐波那契数列

故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……

 function Fibonacci2 (n) {
     if( n === 1 || n===2 ) {return 1};
     return Fibonacci2 (n - 2) +Fibonacci2 (n - 1);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值