数据结构_002

  • Data Structure
    • 1.什么是数据结构
      • 1.1基本概念和术语
        • 基本概念
          • 数据
            • 任何可以被计算机处理的信息
          • 数据元素
            • 数据结构讨论的基本单位
          • 数据项
            • 数据结构中讨论的最小单位
          • 数据对象
            • 性质相同的数据元素的集合,数据的一个子集 
              • 整数数据对象
              • 字母字符数据对象
          • 数据结构(狭义)
            • 带结构的数据元素的集合
            • 是相互之间存在一种或多种特定关系的数据元素的集合
              • 关系不同结构不同
              • 数据的逻辑结构分类(数据关系)
                • 线性结构
                • 树形结构
                • 图结构或网状结构
                • 集合结构
            • 是相互之间存在着某种逻辑关系的数据元素的集合
          • 数据结构形式定义
            • 数据结构是一个二元组
            • 数据,结构(D,S)
          • 数据的存储结构
            • 逻辑结构在计算机中的表示
            • 数据元素的映像
              • 用二进制位()的位串表示数据元素
            • 关系的映像
              • 顺序映像和非顺序映像
                • 顺序存储
                  • 以相对的存储位置表示后继关系,整个存储结构中只含数据元素本身的信息
                • 链式存储
                  • (指针结构)需要用一个和X在一起的附加信息指示y的存储位置
        • 数据类型(Data Type)
          • Like int float string
          • 规定了其取值范围和运算内容
          • 不同类型的变量的取值和所能进行的操作是不同的
          • 是一个值的集合和定义在此集合上的一组操作的总称
        • 抽象数据类型(Abstract Data Type)
          • 概念
            • 一个数学模型以及定义在此数学模型上的一组操作
          • 包含内容
            • 数据对象
            • 数据关系
            • 操作
              • 算法设计
          • 重要特征
            • 数据抽象
            • 数据封装
      • 1.2抽象数据类型的表示与实现
        • 概念
          • 用已有的数据类型来表示实现新的数据类型和结构
      • 1.3算法和算法分析
        • 算法
          • 概念
          • 特征
            • 有穷性
            • 确定性
            • 可行性
            • 有输入
              • 可以无
            • 有输出
              • 必须有
        • 算法设计的要求
          • 目标
            • 正确性
              • 不含语法错误
              • 对机组输入数据得到满足要求的结果
              • special典型苛刻的数据能得到满足要求的结果
                • 以这个为衡量算法是否标准的依据
              • 对于一切合法的输入数据都能得出满足要求的结果
            • 可读性
              • 易读
            • 健壮性
              • 输入非法时恰当地表示
              • 处理出错方法不是中断执行而是返回一个表示错误或错误性质的值,以便在更高的抽象层次上进行处理
            • 高效率与低存储量的需求
              • 与问题的规模有关
              • 需求时间和空间越少越好
        • 算法效率的度量
          • 度量方法
            • 事后统计法
              • 缺点
                • 必须执行程序
                • 其他因素掩盖算法本质
            • 事前分析估算法
              • 消耗时间取决因素
                • 算法选用的策略
                • 问题的规模
                • 编写程序的语言
                • 编译程序产生的机器代码的质量
                • 计算机执行指令的时间
              • 抛开硬件软件原因
                • 只依赖于问题的规模
                • 换句话说是问题规模的函数
                • 算法中基本操作重复执行的次数是问题规模n的摸个函数f(n)
                • 算法的时间度量记作 T ( n ) = O ( f ( n )  )
                • 即时间复杂度
          • 算法的时间复杂度
            • 算法 = 控制结构 + 原操作
            • (固有数据来行的操作)
              • 算法的执行时间与原操作执行次数之和成正比
          • 算法效率的度量
            • O(n2)
          • 算法的存储空间需求
            • S(n) = O ( g ( n ) )
              • 空间需求随着问题规模n的增大而同g(n)的增长率相同
            • 算法的存储量
              • 输入数据所占空间
              • 程序本身所占空间
              • 辅助变量所占空间
            • 几种占用空间情况
              • 若输入数据所占空间只取决于问题本身,和算法无关,则只需要分析除输入和程序之外的辅助变量所占额外空间
              • 若所需额外空间相对于输入数据量来说是常数,则称此算法为原地工作
              • 若所需存储量依赖于特定的输入,则通常按最坏情况考虑
    • 2.线性表
      • 2.1线性表的类型定义
        • 抽象类型定义
          • 一个线性表是n个数据元素的有限序列,称 i ai 在线性表之中的位序
        • 基本操作
          • 结构初始化
            • InitList(&L)
          • 结构销毁
            • DestroyList(&L)
          • 引用型操作
          • 不改变表本身
            • 判断是否为空
              • ListEmpty( L )
            • 求线性表长度
              • ListLength( L )
            • 求数据元素的前驱
              • PriorElem( L, cur_e, &pre_e )
            • 求后继
              • NextElem( L, cur_e, &next_e )
            • 取某个数据元素
              • GetElem( L, I, &e )
            • 定位某个值的位置
              • LocateElem(L, e, compare() )
            • 遍历线性表
              • ListTraverse( L, visit() )
          • 加工型操作
          • 改变表本身
            • 线性表置空
              • ClearList( &L )
            • 改变数据元素的值
              • PutElem( &L, I, &e )
            • 插入数据元素
              • ListInsert( &L, I, e )
            • 删除数据元素
              • ListDelete( &L, I, &e )
        • 要求操作
          • 例一:求A集合并B集合,最后得到新的集合仍为A集合
            • 1.从线性表LB中依次查看每个数据元素
              • GetElem (LB,i )   =>   e
            • 2.根据每个值在线性表LA中进行查访
              • LocateElem(LA,e,equal())
            • 3.若不存在,则插入之
              • ListInsert(LA, n+1 ,e)
          • 例二:已知LALB都按照非递减排列,求一个LC为将LALB合并并按照非递减排列
            • void MergeList(List La, List Lb, List &Lc)
            • {
            •     //已知线性表La Lb中数据元素按值非递减有序排列,归并La
            •     //Lb得到新的线性表LcLc中的数据元素也按值非递减排列。
            •     InitList(Lc); // 构造空的线性表 Lc
            •     i = j = 1;
            •     k = 0;
            •     La_len = ListLength(La);
            •     Lb_len = ListLength(Lb);
            •     while ((i <= La_len) && (j <= Lb_len))
            •     {
            •         // La Lb 均非空,i = j = 1, k = 0 GetElem(Lai ai);
            •         GetElem(Lb j bj);
            •         if (ai <= bj)
            •         { //ai插入到Lc
            •             ListInsert(Lc++ k ai);
            •             ++i;
            •         }
            •     }
            •     else
            •     { //bj插入到Lc
            •         ListInsert(Lc++ k bj);
            •         ++j;
            •     }
            •     //当上面的循环结束即意味着有一个线性表已经全部倒入LC
            •     //此时应该将另一个未完全导入的表整体移进去
            •     while (i <= La_len)
            •     { // La不空时
            •         GetElem(La i++ ai);
            •         ListInsert(Lc++ k ai);
            •     } // 插入 La 表中剩余元素
            •     while (j <= Lb_len)
            •     { // Lb不空时
            •         GetElem(Lb j++ bj);
            •         ListInsert(Lc++ k bj);
            •     } // 插入 Lb 表中剩余元素
            • } // merge_list
            • 算法一
      • 2.2线性表的顺序表示和实现
        • 概念
          • 用一组地址连续的存储单元依次存放线性表的数据元素
        • 公式表示
          • LOC(ai) = LOC(a1) + (i-1)×C
          • 基地址
            • LOC(a1)
        • C语言描述
          • 初始化
            • Status InitList_Sq(SqList &L)
            • { // 构造一个空的线性表
            •     L.elem = (ElemType) * malloc(LIST_ INIT_SIZE * sizeof(ElemType));
            •     L.length = 0;               //空表长度为0
            •     L.listsize = LIST_INIT_SIZE //初始存储容量
            • } // InitList_Sq
          • 定义
            • #define LIST_INIT_SIZE 100
            • // 线性表存储空间的初始分配量
            • #define LISTINCREMENT 10
            • // 线性表存储空间的分配增量
            • typedef struct
            • {
            •     ElemType *elem; // 存储空间基址
            •     int length;     // 当前长度
            •     int listsize;   // 当前分配的存储容量
            •     //( sizeof(ElemType)为单位)
            • } SqList; // 俗称 顺序表
          • 插入
            • Status ListInsert_Sq(SqList &L, int i, ElemType e)
            • {
            •     // 在顺序表L的第 i 个元素之前插入新的元素e
            •     // i 的合法范围为 1 ≤i ≤L.length+1 ......//见下页//
            •     q = &(L.elem[i - 1]); // q 指示插入位置
            •     for (p = &(L.elem[L.length - 1]); p >= q; --p)
            •     {
            •         *(p + 1) = *p; // 插入位置及之后的元素右移 *q = e; // 插入e
            •     }
            •     ++L.length; // 表长增1
            •     return OK;
            • } // ListInsert_Sq
            • if (i < 1 || i > L.length + 1)
            •     return ERROR; // 插入位置不合法
            • if (L.length >= L.listsize)
            • {
            •     // 当前存储空间已满,增加分配
            •     newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));
            •     if (!newbase)
            •         exit(OVERFLOW);          // 存储分配失败
            •     L.elem = newbase;            // 新基址
            •     L.listsize += LISTINCREMENT; // 增加存储容量
            • }
          • 删除
            • Status ListDelete_Sq(SqList &L, int i, ElemType e)
            • {
            •     // 在顺序表L中删除第 i 个元素,并用e返回其值,
            •     // i 的合法范围为 1≤i≤L.length
            •     if ((i < 1) || (i > L.length))
            •         return ERROR;
            •     // i值不合法
            •     p = &(L.elem[i - 1]);      // p 为被删除元素的位置
            •     e = *p;                    // 被删除元素的值赋给 e
            •     q = L.elem + L.length - 1; // 表尾元素的位置
            •     for (++p; p <= q; ++p)
            •         *(p - 1) = *p;
            •     // 被删除元素之后的元素左移
            •     --L.length // 表长减1
            •       return OK;
            • } // ListDelete_Sq
          • 查找
            • int LocateElem_Sq(SqList L, ElemType e, Status (*compare)(ElemType, ElemType))
            • {
            •     // 在顺序表中查询第一个满足判定条件的数据元素,
            •     // 若存在,则返回它的位序,否则返回 0
            •     i = 1;      // i 的初值为第 1 元素的位序
            •     p = L.elem; // p 的初值为第 1 元素的存储位置
            •     while (i <= L.length && !(*compare)(*p++, e))
            •         ++i;
            •     if (i <= L.length)
            •         return i;
            •     else
            •         return 0;
            • } // LocateElem_Sq
        • 时间复杂度:除查找为O(1)外均为O(n)
          • 不准确
      • 2.2线性表的链式表示和实现
        • 线性链表概念
          • 用一组地址任意的存储单元存放线性表的数据元素
        • 形象表示
        • C语言描述
          • 定义&单位
            • Typedef struct LNode
            • {
            •     ElemType data;      // 数据域
            •     struct Lnode *next; // 指针域
            • } LNode, *LinkList;
            • LinkList L; 
            • // L 为单链表的头指针,它指向表中第一个结点。
          • 插入
            • Status GetElem_L(LinkList L, int i, ElemType &e)
            • {
            •     // L是带头结点的链表的头指针,以 e 返回第 i 个元素
            •     p = L->next;
            •     j = 1; // p指向第一个结点,j为计数器
            •     while (p && j < i)
            •     {
            •         p = p->next;
            •         ++j;
            •     }
            •     // 顺指针向后查找,直到 p 指向第 i 个元素或 p 为空
            •     if (!p || j > i)
            •         return ERROR; // i 个元素不存在
            •     e = p->data;      // 取得第 i 个元素
            •     return OK;
            • } // GetElem_L
          • 删除
            • Status ListDelete_L(LinkList L, int i, ElemType &e)
            • {
            •     // 删除以 L 为头指针(带头结点)的单链表中第 i 个结点
            •     p = L;
            •     j = 0;
            •     while (p->next && j < i - 1)
            •     {
            •         p = p->next;
            •         ++j;
            •     }
            •     // 寻找第 i 个结点,并令 p 指向其前驱
            •     if (!(p->next) || j > i - 1)
            •         return ERROR; // 删除位置不合理
            •     q = p->next;
            •     p->next = q->next; // 删除并释放结点
            •     e = q->data;
            •     free(q);
            •     return OK;
            • } // ListDelete_L
          • 查找
            • Status GetElem_L(LinkList L, int i, ElemType &e)
            • {
            •     // L是带头结点的链表的头指针,以 e 返回第 i 个元素
            •     p = L->next;
            •     j = 1; // p指向第一个结点,j为计数器
            •     while (p && j < i)
            •     {
            •         p = p->next;
            •         ++j;
            •     }
            •     // 顺指针向后查找,直到 p 指向第 i 个元素或 p 为空
            •     if (!p || j > i)
            •         return ERROR; // i 个元素不存在
            •     e = p->data;      // 取得第 i 个元素 return OK;
            • } // GetElem_L
        • 时间复杂度:除查找和插入为O(n)外均为O(1)
          • 不准确

你可能感兴趣的:(学习总结)