标签:over 链式 度量 语言 tac 算法 fifo 特点 ring
数据结构:带“结构”的数据元素的集合;
数据元素:是数据集合中的一个“个体”,是数据结构中讨论的基本单位;
数据项:是数据结构中讨论的不可再分的最小单位;
二元组:
格式:
Data_Structure=(D,R)
? D={di| 1≤i≤n,n≥0}
? R={rj | 1≤j≤m,m≥0}
? 注:rj表示集合R中的第j个关系,每个关系用序偶表示。 序偶<x,y>(x,y∈D) x为第1个元素,y为第2个元素。
举例:
LinearList={D,R}
D={A,B,C}
R={<A,B>, <B,C>,<C,D>}
顺序、链式存储结构:逻辑上相邻存储在物理位置(地址)上是否相邻;
ADT Complex {
数据对象:
? D={e1,e2 | e1,e2均为实数}
数据关系:
? R={<e1,e2> | e1是复数的实数部分,e2 是复数的虚数部分 }
基本操作:
AssignComplex(&z,v1,v2):构造复数Z ? DestroyComplex(&z):销毁复数z ? GetReal(z,&real):返回复数z的实部值 ? GetImag(z,&Imag):返回复数z的虚部值 ? Add(z1,z2,&sum):返回两个复数z1、z2的和 ? ……
} ADT Complex
算法:
? 算法的定义:对特定问题求解步骤的一种描述,它是指令 的有限序列,每一条 指令表示一个或多个操作。
? 算法的特性:有穷性、确定性、可行性、输入、输出;
? 算法的描述:自然语言、流程图、程序设计语言、伪代码;
? 算法设计的目标:正确性、可使用性、可读性、健壮性、时间效率高与存储量 低;
? 算法效率:
算法中基本运算执行次数T(n)是问题规模n的某个函数
记作: T(n) = O(f(n))
T(n):基本运算执行次数
n:问题规模
“O”标记的形式定义: 若f(n)是正整数n的一个函数,则T(n)=O(f(n)) 表示存在一个正的常数M,使得当n≥n0时都满足: |T(n)|≤M|f(n)|
换句话说:当自变量n趋向于无穷大时,两者的比值 是一个小于等于M的常数。 如T(n) = n2, f(n) = 3n2+2n+1000只求出T(n)的最高阶,忽略其低阶项和常系数, 这样既可简化T(n)的计算,又能比较客观地反映 出当n很大时算法的时间性能。
例如,T(n) = 3n2 + 2n + 1000 = O(n2)
? (2)空间复杂度:算法在运行过程中临时占用的存储空间的度量 。一般也是问题规模n的的函数S(n)=O(g(n))
? (1)定义:具有相同特性的数据元素的一个有限序列。 一般表示为 (a1, a2 ...,ai-1, ai, ai+1, ..., an) ;
? (2)基本运算:
▲LocateElem(L,e):返回L中第一个值域与e相等的 逻辑位序。若这样的元素不存在,则返回0 ▲GetElem(L,i,&e):用e返回L中第i个元素的值 ▲ListInsert(&L,i,e):在L中第i个元素之前插入e ▲ListDelete(&L,i,&e):删除L中第i个元素 ▲LocateElem(L,e):返回L中第一个值域与e相等的 逻辑位序。若这样的元素不存在,则返回0 ▲GetElem(L,i,&e):用e返回L中第i个元素的值 ▲ListInsert(&L,i,e):在L中第i个元素之前插入e ▲ListDelete(&L,i,&e):删除L中第i个元素
? (3)线性表的存储:
? 顺序存储:
? 【1】定义:使用一块地址连续的存储空间,按照线性 表中元素的逻辑顺序依次存放相应元素。
? 【2】?随机存储取特性:
? 利用地址相邻的特性,根据公式进行地址的计算:
? LOC(ai)=LOC(a1)+(i-1)*len
? ?LOC(a1):线性表的基地址
? ?len: 每个元素的长度
? 【3】在C语言中的定义(数组):
#define MaxSize 50
typedef int ElemType; //ElemType类型实际上是int
typedef struct
{
ElemType data[MaxSize]; //存放顺序表中的元素
int length; //顺序表的长度
}SqList; //SequenceList, 顺序表
? 链式存储:
? 【1】特点:线性表中的数据元素存放在一组地址任意 的存储节点,节点之间使用“链”进行连接。
? 【2】链表存储密度低:存储密度=数据所占空间/节点所占用空间(节点所占用空间=数据占用空间+指针占用空间)
? 【3】节点和单链表类型的定义如下(链表):
typedef struct LNode //定义单链表节点结构体
{
ElemType data; //数据域
struct LNode *next; //指向后继节点
} LinkList;
? 【4】重点代码:
①新建节点:
s = new LNode;
s->data = e;
s->next = p->next;
p->next = s;
②删除第i个节点:
q = p->next;
e = q->data;
p->next = q->next;
delete q;
③头插法
void CreateListF(LinkList *&L, ElemType a[], int n)
{ LinkList *s;
int i;
L = new LNode;
L->next = NULL; //创建头节点,其next域置为NULL
for (i=0; i<n; i++){ //循环建立数据节点
s = new LNode;
s->data = a[i]; //创建数据节点*s
s->next = L->next; //将*s插在原开始节点之前,头节点之后
L->next = s;
}
}
④尾插法
void CreateListR(LinkList *&L, ElemType a[], int n)
{ LinkList *s,*r;
int i; L = new LNode; //创建头节点
r=L; //r始终指向尾节点,开始时指向头节点
for (i=0; i<n; i++) //循环建立数据节点
{ s = new LNode;
s->data = a[i]; //创建数据节点*s
r->next = s; //将*s插入*r之后
r = s;
}
r->next = NULL; //尾节点next域置为NULL
}
? 【5】双链表:节点中有两个指针域 ?一个指向后继节点,一个指向前驱节点。(方便查找一个节点的前驱与后继)
typedef struct DNode //声明双链表节点类型
{
ElemType data;
struct DNode *prior; //指向前驱节点
struct DNode *next; //指向后继节点
}DLinkList;
后进先出的线性表.
? 【1】特点:
? ①栈顶元素先出栈,栈底元素后出栈;
? ②时进时出→元素未完全进栈时,即可出栈;
? 【2】基本操作:
▲InitStack(&S) //操作结果:构造一个空栈 S
▲DestroyStack(&S) //初始条件:栈 S 已存在 操作结果:栈 S 被销毁
▲StackEmpty(S) //初始条件:栈S已存在 操作结果:若栈S为空栈,则返回TRUE,否则 FALSE
▲StackLength(S) //初始条件:栈S已存在。 操作结果:返回S的元素个数,即栈的长度
▲GetTop(S, &e) //查看栈顶元素,不同于Pop 初始条件:栈 S 已存在且非空。 操作结果:用 e 返回 S 的栈顶元素。
▲ClearStack(&S) //初始条件:栈 S 已存在。 操作结果:将 S 清为空栈。
▲Push(&S, e) //初始条件:栈 S 已存在。 操作结果:插入元素 e 为新的栈顶元素。
▲Pop(&S, &e) //初始条件:栈 S 已存在且非空。 操作结果:删除S的栈顶元素,并用e返回其值
? 一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。
? ? 初始分配量:MAXSIZE
? ? 栈底指针base,总是指向栈底。
? ? 栈顶指针top。栈空时,top等于base;栈非空时, 总是指向栈顶元素+1的位置。
? ? 插入一个栈顶元素,指针top增1;
? 删除一个栈顶元素,指针top减1;
? ? 非空栈中的栈顶指针始终在栈顶元素的下一个位置上。
#define MAXSIZE 100;//存储空间初始分配量
typedef int ElemType;
typedef int Position;
typedef struct {
ElemType *base; //栈构造前和销毁后,base的值为NULL
Position top; //栈顶指针
int size; //当前已分配的存储空间,以元素为单位
} SqStack;
注:链栈中指针的方向指向前驱结点。(头插法)
typedef struct node{
LElemType data;
struct node *link;
}StackNode,*LinkStack;
? 插入和删除(进栈/出栈)只能在表头位置(栈顶)进行;
? 链栈中的结点是动态产生的,可不考虑上溢问题;
? 无需附加头结点,栈顶指针就是链表(即链栈)头指针。
Status Push(LinkStack &S , ElemType e)
{/*将元素e进链栈 */
StackNode *p;
p = new StackNode;
if (!p) exit(OVERFLOW);
p->data = e;
p->link = S;
S = p;
return OK;
}
Status Pop(LinkStack &S,SElemType &e)
{/*从链栈顶取出元素存至e */
if (s->next==NULL)
return false;
StackNode *p;//临时指针,用来销毁栈顶元素
e = S->data;
p = S;
S = S->next;
delete p;
return OK;
}
先进先出(FIFO) 的 线性表. 在表一端插入,在另一 端删除.
? 【1】基本运算:
▲ InitQueue(&Q) //操作结果:构造一个空队列Q。
▲ DestroyQueue(&Q) //初始条件:队列Q已存在。 操作结果:队列Q被销毁,不再存在。
▲ QueueEmpty(Q) //初始条件:队列Q已存在。 操作结果:若Q为空队列,则返回TRUE,否则返回 FALSE
▲ QueueLength(Q) //初始条件:队列Q已存在。 操作结果:返回Q的元素个数,即队列的长度。
▲ GetHead(Q, &e) //初始条件:Q为非空队列。 操作结果:用e返回Q的队头元素。
▲ ClearQueue(&Q) //初始条件:队列Q已存在。 操作结果:将Q清为空队列。
▲ EnQueue(&Q, e) //入队 初始条件:队列Q已存在。 操作结果:插入元素e为Q的新的队尾元素。
▲ DeQueue(&Q, &e) //出队 初始条件:Q为非空队列。 操作结果:删除Q的队头元素,并用e返回其值。
? 【2】队列类型的实现:
(1)顺序队列:
#define MAXQSIZE 100 //最大队列长度
typedef struct
{
QElemType *base; //初始化动态分配存储空间
int front, rear ; /*队首、队尾*/
}SqQueue;
SqQueue Q;
typedef int QElemType;
typedef struct QNode {// 结点类型
QElemType data;
struct QNode *next;
} QNode, *QueuePtr;
typedef struct { // 链队列类型
QueuePtr front; // 队头指针
QueuePtr rear; // 队尾指针
} LinkQueue;
入/出队列运算 利用“模运算”,则:
入队:Q.rear=(Q.rear+1)%m
出队:Q.front=(Q.front+1)%m
判断队空队满:
队空:front==rear 队满:front==rear
少用一个元素空间:
队空:Q.rear = Q.front
队满:(Q.rear+1) % m = Q.front
【1】定义:由零个或多个字符组成的有限序列,一般记 为:s=‘a1a2...an‘ (n≥0)
*串中字符的个数n称为串的长度;包含零个字符, 即长度为零的串称为空串,用ф表示。(非空格串;空格串是一个或多个空格组成的)
? ? 子串:串中任意个连续的字符组成的子序列。
? ? 主串:包含子串的串称为主串。
? ? 位置:字符在序列中的序号。
? ?子串在主串中的位置以子串的第一个字符在主串中 的位置来表示。
? ? 相等:两个串的长度相等,并且对应位置的字符 都相同。
【2】基本运算:
▲ StrEmpty(S) //初始条件:串S已存在。 操作结果:若S为空串,则返回TRUE,否则返回 FALSE。 ‘‘表示空串,空串的长度为零。
▲ StrCompare(S, T) //初始条件:串S和T存在。 操作结果:若S>T,则返回值>0; 若S=T,则返回值=0; 若S<T,则返回值<0。 等价于C语言中的strcmp函数(按ASCII码值进行大 小比较) 原理:对字符串的每个字符逐个进行比较。
▲ StrLength(S) //初始条件:串 S 存在。 操作结果:返回 S 的元素个数,称为串的长度。 等价于C语言中的strlen函数
▲ Concat(&T, S1, S2) //初始条件:串 S1 和 S2 存在。 操作结果:用T返回由S1和S2联接而成的新串。
▲ SubString(&Sub, S, pos, len) //初始条件:串 S 存在,1≤pos≤StrLength(S) 且 0≤len≤StrLength(S)-pos+1。 操作结果:用 Sub 返回串 S 的第 pos 个字符 起长度为 len 的子串。
▲ Index(S, T, pos) 初始条件:串S和T存在,T是非空串, 1≤pos≤StrLength(S)。 操作结果: 若主串 S 中存在和串 T 值相同的子 串, 则返回它在主串 S 中第pos个字符之后第一 次出现的位置;否则函数值为0。 ? “子串在主串中的位置”指子串中的第一个字符在 主串中的位序。
▲ Replace(&S, T, V) 初始条件:串S, T和V均已存在,且T是非空串 操作结果:用 V 替换主串 S 中出现的所有与 (模式串)T 相等的不重叠的子串。
▲ StrInsert (&S, pos, T) 初始条件:串S和T存在, 1≤pos≤StrLength(S)+1 操作结果:在串S的第pos个字符之前插入串T。
▲ StrDelete (&S, pos, len) 初始条件:串S存在1≤pos≤StrLength(S)-len+1。 操作结果:从串S中删除第pos个字符起长度为len 的子串。
▲ ClearString (&S) 初始条件:串S存在。 操作结果:将S清为空串。
【3】算法
? BF算法:
? BF算法的时间复杂度:
若n为主串长度,m为子串长度,最坏情况是
?主串前面n-m个位置都部分匹配到子串的最后一位, 即这n-m位各比较了m次
?最后m位也各比较了1次 总次数为:(n-m)m+m=(n-m+1)m 若m<<n,则算法复杂度O(n*m)
? KMP算法:
参考:https://blog.csdn.net/dark_cy/article/details/88698736
代码:
int Index_KMP(SString S, SString T, int pos) {
// 1≤pos≤StrLength(S)
i = pos; j = 1;
while (i <= S[0] && j <= T[0]) {
if (j == 0 || S[i] == T[j]) { ++i; ++j; } // 继续比较后继字符
else j = next[j]; // 模式串向右移动
}
if (j > T[0])
return i-T[0]; // 匹配成功
else return 0;
} // Index_KMP
标签:over 链式 度量 语言 tac 算法 fifo 特点 ring
原文地址:https://www.cnblogs.com/dcftx/p/12588892.html