Skip to content

gonghui-yu/Data-Structures-and-Algorithms

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 

Repository files navigation

数据结构与算法

程序 = 数据结构 + 算法

数据结构是一门研究非数值计算的程序设计中计算机的操作对象以及它们之间的关系操作的学科。

算法分析

正确性、可读性、健壮性

高效性

  • 时间效率:算法执行所耗费的时间

  • 空间效率:算法执行所耗费的存储空间

  • 时间效率和空间效率有时候是矛盾的

  • 度量方法

    • 事后统计:将算法实现,测算其时间和存储空间开销
    • 事前分析:对算法所消耗的资源的一种估算方法

事前分析

  • 算法运行时间 = 一个简单操作所需的时间 x 简单操作次数
  • 算法运行时间 = Σ 每条语句的执行次数 x 该语句执行一次所需的时间
for {i = 1; i < n; i ++}{   // 执行n+1次,其中n次进入循环体,最后一次执行完结束循环
    for(j = 1; j < n; j++){ // 执行n*(n+1)次
        c[i][j] = 0;    // 执行n*n次
        for(k = 0; k < n; k++){ //执行n*n*(n+1)次
            c[i][j] = c[i][j] + a[i][k] * b[k][j];  // 执行n*n*n次
        }
    }
}

时间复杂度

若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n) = O(f(n)),称O(f(n))为算法的渐进时间复杂度,简称时间复杂度

例: T(n) = 2n^3 + 3n^2 + 2n +1
当n -> ∞ 时,T(n) / n^3 -> 2,这表示n充分大时,T(n)和n^3同阶或同数量级,引入“O”记号,则T(n)可记作:T(n) = O(n^3)

i = 1; // 语句 1
while(i <= n>){
    i = i * 2; // 语句 2
}

// 若循环执行1次,i = 1 x 2 = 2
// 若循环执行2次,i = 1 x 2 x 2 = 2^2
// 若循环执行3次,i = 1 x 2 x 2 x 2 = 2^3
// 若循环执行x次,i = 2^x
// 假设语句2执行x次,且循环条件为i <= n
// 则2^x <= n,则x <= log2 n

随n的增大,不同数量级递增情况

n f(1) f(logn) f(n) f(nlogn) f(n^2) f(n^3) f(2^n) f(n!)
1 1 0 1 0 1 1 2 1
2 1 1 2 2 4 8 4 2
4 1 2 4 8 16 64 16 24
8 1 3 8 24 64 512 256 40320
16 1 4 16 64 256 4096 65536 2.0923E+13
32 1 5 32 160 1024 32768 4.295E+09 2.6313E+35

空间复杂度

算法所需存储空间的度量,记作:s(n) = O(f(n))

算法要占据的空间包含:

  • 算法本身要占据的空间,输出/输出,指令,常数,变量等
  • 算法要使用的辅助空间
// 将一维数组逆序
// 算法1
// 空间复杂度:S(n) = O(1)
for(i = 0; i < n / 2; i++)
{
    t = a[i];
    a[i] = a[n - i - 1];
    a[n - i - 1] = t;
}

// 算法2
// 空间复杂度:S(n) = O(n)
for(i = 0; i < n / 2; i++)
{
    b[i] = a[n - i - 1];
}
for(i = 0; i < n; i++)
{
    a[i] = b[i];
}

线性表

顺序表

链表

查找表头节点(首元节点) 查找表尾节点 查找节点P的前驱节点
带头节点的单链表L L->next
时间复杂度O(1)
从L->next依次向后遍历
时间复杂度O(n)
通过p->next无法找到其前驱节点
带头节点仅设头指针L的循环单链表 L->next
时间复杂度O(1)
从L->next依次向后遍历
时间复杂度O(n)
通过p->next可以找到其前驱节点
时间复杂度O(n)
带头节点仅设尾指针R的循环单链表 R->next
时间复杂度O(1)
R
时间复杂度O(1)
通过p->next可以找到其前驱节点
时间复杂度O(n)
带头节点的双向循环链表L L->next
时间复杂度O(1)
L->prior
时间复杂度O(1)
p->prior
时间复杂度O(1)

比较

比较项目 \ 存储结构 顺序表 链表
空间 存储空间 预先分配,会导致存储空间闲置或溢出现象 动态分配,不会出现存储空间闲置或溢出现象
存储密度 不用为表示节点见的逻辑关系而增加额外的存储开销,存储密度=1 需要借助指针来体现元素间的逻辑关系,存储密度<1
时间 存储元素 随机存取,按位置访问元素的时间复杂度为O(1) 顺序存取,按位置访问元素时间复杂度为O(n)
插入、删除 平均移动约表中一半元素,时间复杂度为O(n) 不需要移动元素,确定插入、删除位置后,时间复杂度为O(1)
适用情况 1.表长变化不大,且能事先确定变化的范围
2.很少进行插入或删除操作,经常按元素位置序号访问数据元素
1.长度变化较大
2.频繁进行插入或删除操作

栈 Stack

栈是一个特殊的线性表,是限定仅在一端(通常是表尾)进行插入和删除操作的线性表。
后进先出(LIFO)

进栈 Push
出栈 Pop

队列 Queue

队列是一种先进先出的线性表,在表尾插入,在表头删除。 先进先出(FIFO)

About

study notes

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages