数据结构和算法基础概述

数据结构

我是一个“栈”

  • 计算机世界中存储和组织数据的
    下面来介绍四种不同的数据存储方式
  • 数组
    存储方式:按顺序存储在连续的内存中
    获取方式:只需要提供位置索引
    注意事项:只能保存相同类型的数据
    特点:读取容易,删除和插入困难。(因为数据内存位置是连续的,如果要删除或插入某一个数据,就要移动此数据之后的所有数据)
    优点:根据索引快速读取数据
  • 链表
    存储方式:不连续的空间,一个节点包含数据和指向下一个节点的指针。
    获取方式:从第一个开始找,直到找到你需要的数据
    特点:寻址困难,删除和插入容易
    优点:可以把一些碎片空间利用起来

  • 原则:先进后出
  • 队列
    原则:先进先出

栈和队列的特点就是存储数据和取出数据的顺序按照一定的规则
时间复杂度:
用O(n)表示, 是一个函数,定性的描述了一个算法的运行时间
从执行次数T(n)可以知道一个算法的时间复杂度
存在常数c,使得当N>=c时T(N)<=f(N),表示为T(n) = O(f(n))
随着输入大小n的增加,算法执行需要的时间的增长速度可以用f(n)表示
从T(n)=>O(n)
T(n)= 常数,O(n)=1,
选择高次项

比如
T(n) = n^3 + n^2 + 29,此时时间复杂度为 O(n^3)。

忽略与最高阶相乘的常数
从算法通过分析和数学运算得到T(n)
1.对于一个循环,假设循环体的时间复杂度是O(n),循环次数是m,则这个循环的时间复杂度是O(nm)
2.多个循环,循环体的时间复杂度是O(n),各循环次数a,b,c...,O(n) = O(n
abc...)。分析的时候要从里向外分析
3.顺序执行的算法,总的时间复杂度等于最大的复杂度
4.条件判断语句,总的时间复杂度等于时间复杂度最大的路径的复杂度
快速排序的时间复杂度
1.最好是O(nlogn)
2.最差是O(n2)

O(n):代表数据量增大几倍,耗时也增大几倍。比如常见的遍历算法

O(logn):当数据增大n倍时,耗时增大logn倍(这里的log是以2为底的,比如,当数据增大256倍时,耗时只增大8倍,是比线性还要低的时间复杂度)。二分查找就是O(logn)的算法,每找一次排除一半的可能,256个数据中查找只要找8次就可以找到目标

O(nlogn):n乘以logn,当数据增大256倍时,耗时增256*8=2048倍。这个复杂度高于线性低于平方。归并排序就是O(nlogn)的时间复杂度

O(1):最低的时空复杂度,也就是耗时与输入数据大小无关,无论输入数据增大多少倍,耗时/耗空间都不变。 哈希算法就是典型的O(1)时间复杂度,无论数据规模多大,都可以在一次计算后找到目标(不考虑冲突的话)

空间复杂度:
描述一个算法所需要的内存空间

递归算法:一个过程或函数在其调用和说明中有直接或间接调用自身的一种方法,通常是把一个复杂大型的问题转化为与原问题相似的规模较小的问题来求解。递归策略只需要少量的程序就可以描述出解题过程所需要的多次重复计算,大大减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。

一般来说,递归需要有边界条件,递归前进段和递归返回段,当边界条件不满足时,递归前进,当边界条件满足时,递归返回。

构成递归所需要的条件:

1.子问题与原始问题为同样的事,且更为简单;

2.不能无限调用,需有个出口,化简为非递归状况处理。

斐波那契数列是典型的递归案例。

递归算法相对于循环来说有一定的性能问题。如果递归的特别深,还有可能会导致栈溢出。

递归算法的设计步骤:

1.确定递归公式

2.确定边界(终了)条件

典型例题:

快速排序算法:取出无序数列的第一个值,然后通过比较将比该值小的元素放到该值的前方,将比该值大的元素放到该值的后方,然后再次对前半部分和后半部分无序的数列进行上述操作。

快速排序算法的平均复杂度是O(nlogn),最糟糕时复杂度是O(n^2)

比较插入、冒泡、归并、快速等不同的排序算法的优劣。从额外空间消耗,平均时间复杂度和最差时间复杂度等方面去比较他们的优缺点。

posted @ 2019-06-28 10:44  书院柯浩然  阅读(222)  评论(0编辑  收藏  举报