五、其它形式的链表
1.双向链表
06_001 |
//线性表的双向链表存储结构 typedef struct DuLNode { ElemType data; //数据域 struct DuLNode *prior; //指向前驱的指针域 struct DuLNode *next; //指向后继的指针域 }DuLNode, *DuLLinkList; |
2.循环链表
最后一个结点的指针域的指针又指回第一个结点的链表
2.4一元多项式的表示
一元多项式
Pn(x) = P0+p1x+p2x2+…+pnxn在计算机中,可以用一个线性表来表示:P=(p0,p1,…pn)
S(x)=1+3x10000-2x20000
Pn(x)=p1xe1+p2xe2+…+pmxem其中:pi是指数ei的项的非零系数,0≤e1<e2<…<em=n
((p1,e1),(p2,e2),…,(pm,em))
P999(x)=7x3-2x12-8x999
抽象数据类型一元多项式的定义如下:
ADT Polynomial
{
数据对象:D={ai|ai∈TermSet, i=1,2,...,m, m≥0}
{TermSet中每个元素包含一个表示系数的实数和表示指数的整数}
数据关系:RI={<ai-1,ai>|ai-1,ai∈D,且ai-1中的指数值<ai的指数值,i=2,…,n}
基本操作:CreatePolyn(&P,m)
操作结果:输入m项的系数和指数,建立一元多项式P
DestoryPolyn(&P)
初始条件:一元多项式P已存在。
操作结果:销毁一元多项式P
PrintPolyn(&P)
初始条件:一元多项式P已存在。
操作结果:打印输出一元多项式P。
AddPolyn(&Pa,&Pb)
初始条件:一元多项式Pa和Pb已存在。
操作结果:完成多项式相加运算,即:Pa=Pa+Pb,并销毁多项式Pb。
SubractPolyn(&Pa,&Pb)
初始条件:一元多项式Pa和Pb已存在。
操作结果:完成多项式相减运算,即:Pa=Pa-Pb,并销毁多项式Pb。
MultiplyPolyn(&Pa,&Pb)
初始条件:一元多项式Pa和Pb已存在。
操作结果:完成多项式相减运算,即:Pa=Pa*Pb,并销毁多项式Pb。
PolynLength(P)
初始条件:一元多项式P已存在。
操作结果:返回一元多项式P中的项数。
} ADT Polynomial
如此定义的多项式可以看成是一个有序表(对其数据元素而言),则多项式定义中的各个操作均可利用有序表的操作来完成。
抽象数据类型Polynomail的实现
typedef struct
{
//项的表示,多项式的项
//作为LinkList的数据元素
floatcoef; //系数
intexpn: //指数
} term, Elemtype;
//若两个类型名:term用于本ADT,ElemType为LinkList的数据对象
typedef LinkList polynominal;
//用带头节点的有序链表表示多项式
int cmp(term a, term b);
//依a的指数值<(或=)(或>)b的指数值,分别返回-1,0,和+1
06_002 |
void CreatePolyn(polynomial &p, int m) { //输入m项的系数好指数,建立表示一元多项式的有序链表P InitList(P); e.coef = 0.0; e.expn = -1; SetCurElem(P, e); //设置头结点的数据元素 for(j = 1; j <= m; ++ i) { //依次输入m个非零项 scanf(e.coef, e.expn); if(! LocateElem(P, e, (*cmp)())) //当前链表中不存在该指数项 InsAfter(P, e); }//for } // CreatePolyn |
本章小节
1.了解线性表的逻辑结构特性是数据元素之间存在着线性关系,在计算机中表示这种关系的两类不同的存储结构是顺序存储结构和链式存储结构。用前者表示线性表简称为顺序表,用后者表示的线性表称为链表。
2.熟练掌握这两类存储结构的描述方法,以及线性表的各种基本操作的实现。
3.能够从时间和空间复杂度的角度综合比较线性表两种存储结构的不同特点极其使用的场合。
第三章栈和队列
3.1 栈的类型定义
3.2 栈的应用举例
3.3 栈的型的实现
3.4 队列的类型定义
3.5 队列类型的实现
3.1 栈的类型定义
ADT Stack
{
数据对象:D={ai|ai∈ElemSet,i=1,2,…,n,n≥0}
数据关系:R1={<ai-1,ai>|ai-1,ai∈D,i=2,…,n}约定an端为栈顶,a1端为栈底。
基本操作:
}ADT Stack
线性表 | 栈 | 队列 |
插入:ListInsert(L,i,e) 1<=i<=ListLength(L)+1 | Insert(s,n+1,e) | Insert(Q,i+1,e) |
删除:ListDelete(L,i,&e) I<=i<=ListLength(L) | Delete(s,n,&e) | Delete(Q,1,e) |
基本操作
InitStack(&S)
DestoryStack(&S)
StackEmpty(S)
StackLength(S)
GetTop(&S)
ClearStack(&S)
Push(&S,e)
Pop(&S,&e)
InitStack(&S)
操作结果:构造一个空栈S。
DestoryStack(&S)
初始条件:栈S已存在。
操作结果:栈S被销毁。
StackEmpty(S)
初始条件:栈S已存在。
操作结果:若栈S为空栈,则返回TRUE,否则返回FALSE。
StackLength(S)
初始条件:栈S已存在。
操作结果:返回S的元素个数,即栈的长度。
GetTop(S,&e)
初始条件:栈S已存在且非空。
操作结果:用e返回S的栈顶元素。
ClearStack(&S)
初始条件:栈S已存在。
操作结果:将S清为空栈。
Push(&S,e)
初始条件:栈S已存在。
操作结果:插入元素e为新的栈顶元素。
Pop(&S,&e)
初始条件:栈S已存在且非空。
操作结果:删除S的栈顶元素,并用e返回其值。
3.2栈的应用举例
例一、数制转换
例二、括号匹配的检查
例三、行编辑程序问题
例四、迷宫求解
例五、表达式求值
例六、实现递归
例一、数制转换
算法基于原理:N=(N div d)*d+N mod d
例如:(1348)10=(2504)8,其运算过程如下:
N | N div 8 | N mod 8 |
1348 | 168 | 4 |
168 | 21 | 0 |
21 | 2 | 5 |
2 | 0 | 2 |