基本概念和术语
数据
- 是客观事物的符号表示 ,所有能输入到计算机中并被计算机程序处理的符号的总称,即数字化的信息
数据元素
数据项是数据的不可分割的‘最小单位’
数据项是对客观事物某一方面特性的数据描述
数据对象
- 是性质相同的数据元素的集合,是数据的一个子集.如字符集合
数据结构
逻辑结构
逻辑结构有4种基本类型:
- 集合:除了属于同一个集合外没有其他关系
- 线性结构:一对一
- 树形结构:一对多
- 图状结构或网状结构:数据元素之间存在多对多的关系
存储结构(物理)
算法
定义
特性
线性结构
线性表
概念
- 线性表 是一种典型的线性结构
- 所有结点具有相同的数据类型
- 当表非空时,记作L=(a1,a2,…,ai…,an)
- a1称为线性表的第一个(首)结点,an称为线性表的最后一个(尾)结点
- a1,a2…..都是ai的前驱,其中ai-1是ai的直接前驱
- ai+1,ai+2都是ai的后继,其中ai+1是ai的直接后继
特点
- 基本特点:线性表中的数据元素是有序的,且是有限的
- 若线性表中的结点是按值或关键字值由小到大或从大到小有序排列,则称线性表是有序的
- 线性表是一种相当灵活的数据结构
顺序存储
- 线性表是物理结构
- 顺序存储:把线性表的结点按逻辑顺序一次存放在一个地址连续的存储单元里用这种方式存储的线性表简称顺序表
- 特点
- 线性表的逻辑顺序于物理顺序一致
- 数据元素之间相邻
1 2 3 4 5
| typedef struct sqlist{ ElemType data[MAX_SIZE];//静态数组->初始化对应(2,1) //ElemType *data 动态数组->初始化对应(2,2) int len;//线性表的长度 }SqList;
|
链式存储
- 例如链表
- 特点:
- 可以连续也可以不连续
- 结点的逻辑顺序和物理顺序不一定相同
- 设置头结点
- 双链表是为了克服单链表的单向性的缺陷而引入的
线性表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| #define MAX_SIZE 100 typedef int ElemType; typedef struct sqlist { ElemType data[MAX_SIZE]; int len; }sqlist;
void initiate(sqlist &L) { L.len = 0; } int length(const sqlist &L) { return L.len; } ElemType get(const sqlist &L, int i)//去下表为i的元素 { if (i < 0 || i >= L.len) { return 0; } return L.data[i]; } int locate(int L[], int e) {
} void insertion(sqlist &L, int i, ElemType e) { if (i<0 || i>L.len||L.len>=MAX_SIZE) { return; } for (int j = L.len - 1; j >= i; --j) { L.data[j + 1] = L.data[j]; } L.data[i] = e; L.len++; return; } ElemType deleteElm(sqlist& L, int i) { ElemType x; //待删除的结点(下标=i) if (L.len == 0) { return 0; } else if (i < 0 || i >= L.len) { return 0; } else { x = L.data[i]; /*保存待删除结点的值*/ /*(A)i之后的所有结点依次前移一位(i+1 ~ n-1) */ for (int k = i + 1; k < L.len; k++) { L.data[k - 1] = L.data[k]; } /*(B)线性表长度-1 */ L.len--; return (x); } } bool empty(sqlist &L) { if (L.len == 0) { return true; } return false; } void clear(sqlist &L) { L.len = 0; }
|
合并两个链表
这里用合并两个方程组举例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| typedef struct ploy { float coef; int expn; struct ploy* next; } ploy;
ploy* createlink() { ploy* h = (ploy*)malloc(sizeof(ploy)); h->next = NULL; ploy* r = h; int n, i; printf("输入系数个数\n"); scanf("%d", &n); for (i = 0; i < n; i++) { ploy* p = (ploy*)malloc(sizeof(ploy)); printf("输入系数,指数\n"); scanf("%f,%d", &(p->coef), &(p->expn)); // 使用地址运算符& r->next = p; p->next = NULL; r = p; } // 尾插法 return h; }
ploy* merge(ploy* h1, ploy* h2) { ploy* help = (ploy*)malloc(sizeof(ploy)) ; // 不再使用数组 help->next = NULL; ploy* p1 = h1->next, * p2 = h2->next, * ptr, *r =help; // 使用指针变量 while (p1 != NULL && p2 != NULL) { ploy* p = (ploy*)malloc(sizeof(ploy)); // 动态分配内存 if (p1->expn == p2->expn) { p->expn = p1->expn; p->coef = p1->coef + p2->coef; p->next = NULL; p1 = p1->next; p2 = p2->next; } else if (p1->expn < p2->expn) { p->expn = p1->expn; p->coef = p1->coef; p->next = NULL; p1 = p1->next; } else { p->expn = p2->expn; p->coef = p2->coef; p->next = NULL; p2 = p2->next; } r->next = p; p->next = NULL; r = p; } while (p1 != NULL) { ploy* p = (ploy*)malloc(sizeof(ploy)); // 动态分配内存 p->expn = p1->expn; p->coef = p1->coef; p->next = NULL; r->next = p; p->next = NULL; r = p; p1 = p1->next; } while (p2 != NULL) { ploy* p = (ploy*)malloc(sizeof(ploy)); // 动态分配内存 p->expn = p2->expn; p->coef = p2->coef; p->next = NULL; r->next = p; p->next = NULL; r = p; p2 = p2->next; } return help; }
void printlink(ploy* h) { h = h->next; printf("合并后\n"); while (h != NULL) { printf("%.1fx^%d", h->coef, h->expn); if (h->next != NULL) { printf("+"); } h = h->next; } }
int main() { printf("输入第一个链表\n"); ploy* h1 = createlink(); printf("输入第二个链表\n"); ploy* h2 = createlink(); ploy* he = merge(h1, h2); printlink(he); return 0; }
|
两个方程组相乘
思路是建立一个链表来储存一个链表第一个数去×另一个的所有
再建立一个空链表
最后将两个链表相加,不断往后得到答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| ploy* mul(ploy* h1, ploy* h2) { ploy* help = (ploy*)malloc(sizeof(ploy)); help->next = NULL; ploy* res = (ploy*)malloc(sizeof(ploy)); res->next = NULL;; ploy* t = h2->next; while (t != NULL) { ploy* r = help; ploy* s = h1->next; while (s != NULL) { ploy* p = (ploy*)malloc(sizeof(ploy)); p->coef = s->coef * t->coef; p->expn = s->expn + t->expn; r->next = p; p->next = NULL; r = p; s = s->next; } res = merge(res, help); // 将当前计算得到的结果链表和之前的结果链表合并 t = t->next; } return res; }
|
树
二叉树