dsa-基础

0.概念

数据结构

逻辑结构

  • 集合
  • 线性

物理结构 (存储结构)

  • 线性存储 : 元素存储必须是连续的
  • 链式存储 :指针地址
  • 索引存储 :索引表(关键字 地址)
  • 散列存储 (哈希存储):(关键字 直接计算出内存地址)

复杂度

时间复杂度

事前预估 时间开销 T ( n ) T(n) T(n)问题规模n的关系
执行次数 x x x x = f ( n ) x=f(n) x=f(n),复杂度与 f ( n ) f(n) f(n)的数量级 T ( n ) T(n) T(n)
1 < l o g n < n < n l o g n < n 2 < n 3 < 2 n 1<logn<n<nlogn<n^2<n^3<2^n 1<logn<n<nlogn<n2<n3<2n

估算策略

  • 忽略顺序执行语句
  • 只关注循环部分,且关注其中的一个循序语句
  • 只关注嵌套循环中最深层中的执行语句

空间复杂度

与内存空间(通常与字节为单位)

估算策略

找到所占空间与问题规模相关的变量

1. 线性表

数据元素的数据类型相同
有序
数量有限

索引:–> 位序
第一个元素:表头
前一个元素:直接前驱
后一个元素:直接后继

顺序表(数组)

顺序(连续)存储

  • 随机访问(随机存取)

O(1)

  • 插入、删除

O(n)

  • 查找

按位查找: O(1) ,因为是随机存取的
按值查找: O(n)

链表

链式存储

单链表

  • 带头结点

  • 不带头结点 -建议使用

  • 插入、删除 (按位序) ???

O(n) 相当于查找耗时

  • 查找

O(n)

  • 尾插法

普通尾插法 O ( n 2 ) O(n^{2}) O(n2) – 见例子 ‘dsa-cpp

双链表

在单链表的基础上,加上一个指向prior的前向指针

循环链表

在单链表的基础上,最后的一个尾结点指向了头结点
给定一个节点,可以找到链表中的任意其他节点(单链表只能找到该节点的后继节点)

静态链表

单链表在内存中是随机存储的
静态链表在内存中是连续存储(注意:不是顺序存储)的
头结点的地址+游标*字节大小
在这里插入图片描述

顺序表/链表

  • 顺序表

顺序存储、随机存取
连续内存分配不方便,插入删除不方便

  • 链表

链式存储,不能顺序存取
离散空间分配方便,插入删除方便

只允许在一端进行插入或删除操作的线性表
后进先出(LIFO)

顺序栈

增删改查 O(1)

链式栈

一般使用头插法

队列

只允许在一端进行插入,在另一端删除的线性表
先进先出(FIFO)

这里讨论的循环队列

顺序循环队列

利用数组实现

第一种实现方法 – 见例子
在某些情况下会浪费一个存储空间
在这里插入图片描述

链表队列

利用链表实现

双端队列

运算两端插入、两端删除

2. 递归

C语言教程文档
实际上是 函数调用栈
函数调用

调用返回地址
实参
局部变量

void main()
{
    int a,b,c;
    func1(a,b);
    c=a+b;
}

void func1(int a,int b)
{
    int x;
    func2(x);
}

void func2(int x)
{
    int m,n;
}

func1()的地址,func1() 函数中的局部变量a,b
main() 函数中的局部变量 a,b
main()

在这里插入图片描述


在这里插入图片描述

递归与栈

阶乘例子

#include <iostream>
using namespace std;

int factorial(int n)
{
    if (n==0 || n==1)
    {
        return 1;
    }
    else
    {
        return n*factorial(n-1);
    }
}

int main()
{
    int x=factorial(10);
    cout<<x<<endl;

    return 0;
}

在这里插入图片描述


在这里插入图片描述

3. 矩阵

对称矩阵

行优先存储下
一维数组下标与对称矩阵数据下标的映射函数
eg1:假设一维数组是从0开始;二维数组(不是下图所示)也是从0开始的:
a [ i ] [ j ] − − > a [ i ∗ i + 1 2 + j ] a[i][j] --> a[i* \frac{i+1}{2}+j] a[i][j]>a[i2i+1+j]
1 + 2 + . . . + ( i ) + ( j + 1 ) − 1 = i ∗ i + 1 2 + j 1+2+...+(i)+(j+1)-1 = i* \frac{i+1}{2}+j 1+2+...+(i)+(j+1)1=i2i+1+j

eg2:假设一维数组是从0开始;二维数组(如下图所示)也是从1开始的:
a [ i ] [ j ] − − > a [ ( i − 1 ) ∗ i 2 + j − 1 ] a[i][j] --> a[(i-1)* \frac{i}{2}+j-1] a[i][j]>a[(i1)2i+j1]
1 + 2 + . . . + ( i − 1 ) + j − 1 = ( i − 1 ) ∗ i 2 + j − 1 1+2+...+(i-1)+j-1 = (i-1)* \frac{i}{2}+j-1 1+2+...+(i1)+j1=(i1)2i+j1

在这里插入图片描述

三角矩阵

  • 上三角
  • 下三角

见王道视频

稀疏矩阵

  • 方法1

顺序存储: 三元组<行,列,值>
结构体数组
在这里插入图片描述

  • 方法2

链式存储:十字链表法

在这里插入图片描述

4. 字符串

索引从0开始
位序/位置从1开始

字符串是一种特殊的线性表

数组形式

  • 静态存储

char ch[]

  • 动态存储

char *ch=(char *)malloc(length*sizeof(char))

在这里插入图片描述

链表形式

链表形式存储

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值