课程地址:
https://www.bilibili.com/video/BV1nJ411V7bd
专业术语概览:
数据 Data
能输入计算机且被计算机处理的各种符号的集合
1、是信息的载体
2、是对客观十五符号化的表现
3、能够被计算机识别,存储,加工
分类:
数值型,整数,实数
非数值型,文字,图像,声音
数据元素 DataElement
是 数据元素的基本单位,在程序中作为一个整体进行处理
也称为元素,记录,节点,顶点
数据项 DataItem
构成上述的数据元素的最小单位
三者关系:
数据 > 数据元素 > 数据项
表 > 记录 > 字段
数据对象 DataObject
性质相同的数据元素的集合,数据的一个子集
数据对象是性质相同的数据元素的集合
数据结构 DataStructure
数据元素之间的关系构成了数据的结构
存在一种或多种特定关系的数据元素集合
包含的内容:
1、逻辑结构,抽象描述的关系结构
2、物理结构(存储结构),在内存中的表现形式
3、运算(操作),对数据元素可以实现的一些运算
分类:
是否线性划分:线性结构(线性表,栈,队列,串)和非线性结构(树,图)
逻辑结构划分:集合,线性,树形,图状
基本结构:
1、顺序存储
2、链式存储
3、索引存储
4、散列存储
数据类型 DataType
一组性质相同的值的集合,或者说这个值集合的一组操作的总称
抽象数据类型 AbstractDataType
指一个数学模型,或在此模型上进行的操作
将客观事物抽象成可以在计算机中建立的数据
三元组 D S P
D 数据对象,S 数据对象的关系集合, P 数据对象的基本操作集
抽象数据类型的定义格式
数据类型名 {
数据对象定义
数据关系定义
数据基本操作定义
}
线性表 LinearList
具有相同特性的数据元素的一个有限序列
数据元素的个数N,即表的长度,N=0表示空表
1、非空的线性表,开始节点没有直接前驱,仅有一个直接后驱
2、仅有一个终端节点,没有直接后继,终端节点仅有一个直接前驱
操作:
InitList 初始化
DestroyList 销毁
insert 指定位置插入元素
delete 删除指定元素
clearList 清空
isEmpty 是否为空
isFull 是否为满
length 获取长度
getElementByIndex 根据索引获取元素
IndexOf 根据元素获取索引
priorElement(previous) 获取前驱元素
nextElement 获取后继元素
演示的是静态存储,长度固定不可以动态更改:
PPT课程演示的使用的是C++代码(深感C的纯粹,C++代码就是不伦不类)
也可能是为了便于学生理解才没有使用C代码表现
#include <stdio.h> #include <malloc.h> #include <stdlib.h> typedef enum { true = 1, false = 0 } boolean; typedef struct { float p; int e; } * PPOLYNOMIAL, Polynomial; typedef struct { PPOLYNOMIAL pPolynomial; int length; int maxSize; } * PLIST, List; /** * 初始化线性表,根据maxSize参数在内存中找一块可以访问的连续空间,返回给这个指针 * @param pList * @param maxSize */ void initList (PLIST pList, int maxSize) { pList -> pPolynomial = (PPOLYNOMIAL)malloc(sizeof (Polynomial) * maxSize); if (NULL == pList -> pPolynomial) { printf("初始化失败,程序结束"); exit(-1); } pList -> length = 0; pList -> maxSize = maxSize; } /** * 释放这个指针指向的内存空间,并重置这个指针,不可以重新访问那块空间 * @param pList */ void reliefList(PLIST pList) { free(pList -> pPolynomial); pList -> pPolynomial = NULL; pList -> length = 0; pList -> maxSize = 0; } /** * 长度回到初始值即表示,清空了线性表 * @param pList */ void clearList(PLIST pList) { pList -> length = 0; } /** * 获取长度 * @param pList * @return */ int getLength(PLIST pList) { return pList -> length; } /** * 是否为空 * @param pList * @return */ boolean isEmpty(PLIST pList) { return pList -> length == 0; } /** * 是否为满 * @param pList * @return */ boolean isFull(PLIST pList) { return pList -> length == pList -> maxSize; } /** * 根据索引查找元素 * @param pList * @param index * @param ppolynomial * @return */ boolean getElementByIndex(PLIST pList, int index, PPOLYNOMIAL ppolynomial) { // 索引超出了范围 if (index < 0 || index > pList -> length) return false; // 没有则返回 *ppolynomial = pList -> pPolynomial[index]; return true; } /** * 根据提供的元素查找该元素的索引 * @param pList * @param ppolynomial * @return */ int getIndexByElement(PLIST pList, PPOLYNOMIAL ppolynomial) { for (int i = 0; i < pList -> length; ++i) if (&pList -> pPolynomial[i] == ppolynomial) return i; return -1; } /** * 按指定位置插入元素 * @param pList * @param polynomial * @param index * @return */ boolean insertElement(PLIST pList, Polynomial polynomial, int index) { // 指定位置超出范围或者已经装满,则不能插入 if (index < 0 || index > (pList -> length - 1)) return false; if (isFull(pList)) return false; for (int i = (pList -> length - 1); i >= index ; --i) pList -> pPolynomial[i + 1] = pList -> pPolynomial[i]; pList -> pPolynomial[index] = polynomial; ++ pList -> length; return true; } /** * 按指定位置删除元素 * @param pList * @param index * @return */ boolean deleteElement(PLIST pList, int index) { if (index < 0 || index > (pList -> length - 1)) return false; if (isEmpty(pList)) return false; for (int i = index; i < pList -> length; ++i) pList -> pPolynomial[i - 1] = pList -> pPolynomial[i]; -- pList -> length; return true; } /** * 追加元素 * @param pList * @param polynomial * @return */ boolean append(PLIST pList, Polynomial polynomial) { if (isFull(pList)) return false; pList -> pPolynomial[pList -> length] = polynomial; ++ pList -> length; return true; } /** * 遍历展示list * @param pList */ void traverseList(PLIST pList) { if(isEmpty(pList)) { printf("[]"); return; }; printf("["); for (int i = 0; i < pList -> length; ++i) { if (i == pList -> length - 1) { printf("{%.2f, %d}] ", pList -> pPolynomial[i].p, pList -> pPolynomial[i].e); break; } printf("{%.2f, %d}, ", pList -> pPolynomial[i].p, pList -> pPolynomial[i].e); } } int main() { List list; initList(&list, 3); Polynomial polynomial1 = {10, 22}; append(&list, polynomial1); Polynomial polynomial2 = {333, 444}; append(&list, polynomial2); Polynomial polynomial3 = {23, 35}; insertElement(&list, polynomial3, 0); traverseList(&list); deleteElement(&list, 0); traverseList(&list); reliefList(&list); return 0; }
实现动态存储,我的想法就是重新找可操作的内存空间,
然后复制上去,移除原始指针指向,指向新的地址
/** * 追加元素 * @param pList * @param polynomial * @return */ boolean append(PLIST pList, Polynomial polynomial) { if (isFull(pList)) { pList -> maxSize = pList -> length + pList -> length / 2; PPOLYNOMIAL tempP = (PPOLYNOMIAL)malloc(sizeof(Polynomial) * pList -> maxSize); for (int i = 0; i < pList -> length; ++i) { tempP[i] = pList -> pPolynomial[i]; } free(pList -> pPolynomial); pList -> pPolynomial = tempP; } pList -> pPolynomial[pList -> length] = polynomial; ++ pList -> length; return true; }