课程地址:
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; }