数据结构与算法-2020.3.30笔记

329 阅读6分钟

基本术语名词解释

  • 数据:程序的操作对象用来描述客观事物,可以输入到计算机中并被计算机所识别
  • 数据项:是数据的最小不可分割单位(类似数组中元素的特性)
  • 数据元素:组成数据的的基本单位,由若干个数据项组成(类似数组中的元素)
  • 数据对象:相同的数据元素组成的集合(类似于数组)
  • 结构:数据元素之间不是独立存在的,它具有特定的关系,这个关系即结构
  • 数据结构:数据对象中数据元素的关系,数据结构是一种特殊的结构,因为数据对象中数据元素是有相同的属性
例子:一家公司就是一个数据,员工组成的员工大会就是数据对象,每个员工就是一个数据元素,每个员工的年龄、性别、职位等就是数据项,员工大会中员工之间的关系是数据结构,公司老板以及员工之间关系是一个结构(ps:员工都是打工的,跟老板性质不一样)

逻辑结构与物理结构

  • 逻辑结构:即数据之间的关系,具有以下几种形式
  1. 线性结构:数据之间的关系是一对一的关系,对于非空的线性表和线性结构具有:除了第一个以外每个元素都有一个前驱;除了最后一个以外每个元素都有一个后继常见的线性结构有:栈、链表、数组、字符串、队列
  2. 集合结构:杂乱无序的结构,元素之间没有特定的顺序


  3. 树形结构:数据之间是一对多的关系,常见的有二叉树、红黑树等


  4. 图形结构:数据之间是多对多的


  • 物理结构:就是把逻辑结构的数据存储到计算机中,所以又叫存储结构,它分为四种,即顺序存储、链式存储、索引结构、散列结构。(本文主要说明顺序存储结构、链式存储结构)
  1. 顺序存储结构:在存储时先开辟一段连续的内存空间。由于在顺序存储时,需要预先开辟空间以便数据的记录新的数据。所以在空间的利用率上是有浪费的。连续的空间地址使得我们可以使用下标快速的访问每个数据,同时连续的空间要求我们在插入或者删除数据时需要对操作元素的后续元素进行移位,以保证存储的顺序。
  2. 链式存储结构:不连续的内存空间。优点是大小动态扩展,插入删除效率高,缺点是不能随机访问

算法

  • 算法定义:解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每个指令表示一个或多个操作。
  • 算法特性:输入输出性、又穷性、确定性以及可行性
  • 算法设计要求:确定性(首要条件)、可读性、健壮性、时间复杂度以及空间复杂度低
  • 常见的时间复杂度


  • 空间复杂度:通过计算算法所需要的存储空间实现。算法空间复杂度的计算公式记做:S(n)=n(f(n)),其中n为问题的规模,f(n)为语句关于n所占的存储空间的函数

  • 总结:时间复杂度是算法执行完成需要指令的有限序列,而空间复杂度主要是考虑算法执行时所占用辅助空间,辅助空间越大空间复杂度越高

线性表

  • 顺序表
  1. 表的设计

    /*顺序表设计*/
    typedef struct {    //顺序表的类型
        ElemType *data;    //顺序表的长度    int length;}Model;
    

  2.  表的初始化

    //初始化顺序表Status CreatTable(Model *model){    //为顺序表分配一个大小为MAXSIZE 的数组空间,一经分配则不会因为没有数据而销毁    model->data = malloc(sizeof(ElemType) * MAXSIZE);    //分配失败退出    if (model->data == NULL) {        exit(ERROR);    }    //分配成功则设置空表长度为0    model->length = 0;    return OK;}

  3. 表的删除

    //顺序表插入数据Status insertTable(Model *model,int index, ElemType type){    //越界返回,0的位置是哨兵    if (index<1 || index > model->length + 1) {        return ERROR;    }    //超出存储容量返回    if (model->length == MAXSIZE) {        return ERROR;    }    //判断插入的数据是否在表尾    if (index <= model->length) {//不在表尾        for (int j = model->length - 1; j>= index - 1; j--) {            model->data[j+1] = model->data[j];        }    }    model->data[index - 1] = type;    //表长度自增1    model->length++;    return OK;}

  4. 表的删除

    Status DeleteTable(Model *model,int index){    if (index<1 || index>model->length + 1) {//index<1是因为0的位置时哨兵        return ERROR;    }    //这个删除其实就是数据覆盖    for (int j = index; j<model->length; j++) {        model->data[j-1] = model->data[j];    }    model->length--;    return OK;}

  • 单链表
  1. 定义结点

    //定义结点
    
    typedef struct Node{    ElemType data;    struct Node *next;}Node;typedef struct Node * ModelList;

  2. 初始化单链表

    //初始化链表Status InitList(ModelList *list) {    //生成头结点    *list = (ModelList)malloc(sizeof(Node));    if (*list == NULL) {        return ERROR;    }    //将头结点的指针区域置成空    (*list)->next = NULL;    return OK;
    }

  3. 单链表插入

    //单链表插入Status InsertList(ModelList *list, int index, ElemType type){    int j;    ModelList p,s;    p = *list;    j = 1;    //寻找第index-1个结点(第一个节点是头结点)    while (p && j<index) {        p = p->next;        ++j;    }    //第index-1个节点不存在    if (!p || j>index) {        return ERROR;    }    //生成新结点s    s = (ModelList)malloc(sizeof(Node));    //将e赋值给s的数值域    s->data = type;    //将p的后继结点赋值给s的后继    s->next = p->next;    //将s赋值给p的后继    p->next = s;    return OK;}

  4. 单链表删除

    Status ListDelete(ModelList *list,int index,ElemType *e){    int j;    ModelList p,q;    p = (*list)->next;    j = 1;    //查找第i-1个结点,p指向该结点    while (p->next && j<(index-1)) {        p = p->next;        ++j;    }    //当i>n 或者 i<1 时,删除位置不合理    if (!(p->next) || (j>index-1)) return  ERROR;    //q指向要删除的结点    q = p->next;    //将q的后继赋值给p的后继    p->next = q->next;    //将q结点中的数据给e    *e = q->data;    //让系统回收此结点,释放内存;    free(q);    return OK;}

  5. 前插法创建单链表

    Status CreatHead(ModelList *list,int index){    //创建带头结点的单链接    *list = (ModelList)malloc(sizeof(Node));    (*list)->next = NULL;    //r是头结点    ModelList r = *list;    //循环插入数据    for (int i = 0; i<index; i++) {        //生成新的节点        ModelList p = (ModelList)malloc(sizeof(Node));        p->data = i;        //头结点r指针域赋值给p的指针域        p->next = r->next;        //此时头结点r指向p,即将结点p放在了头结点之后        r->next = p;
        }    return OK;}

  6. 后插法创建单链表

    Status CreatTail(ModelList *list,int index){    //p为每次创建的新结点,r为尾结点    ModelList r;    //创建带头结点的单链接    *list = (ModelList)malloc(sizeof(Node));    r = *list;    //循环插入数据    for (int i = 0; i<index; i++) {        //生成新的节点        ModelList p = (ModelList)malloc(sizeof(Node));        p->data = i;        r->next = p;        r = p;    }    //将表尾指针指向null    r->next = NULL;    return OK;}

ps:第一次写技术博客,憋了将近两天时间,若有错误多多指教,继续努力,坚持下去