第 2 章 线 性 表

64
2.1 线线线线线线线线 2.2 线线线线线线线线线线线 2.3 线线线线线线线线线线线 2.4 线线线线线线线线线线 线 2 线 线 线 线 学学 学学 学学 001 学学 18 002 学学 19 003 学学 19 …… …… …… 100 学学 20

Upload: cathy

Post on 21-Jan-2016

121 views

Category:

Documents


0 download

DESCRIPTION

第 2 章 线 性 表. 2 . 1 线性表的类型定义 2.2 线性表的顺序表示和实现 2.3 线性表的链式表示和实现 2.4 一元多项式的表示及相加. 2.1 线性表的类型定义. 线性表: 是 n 个类型相同的数据元素的有限序列,数据元素之间是一对一的关系,即每个数据元素最多有一个直接前驱和一个直接后继 。. 例 1 英文字母表( A , B , C , … , Z) 是一个线性表 例 2. 数据元素. 线性表的定义. 线性表 是由 n (n≥0) 个类型相同的数据元素 a 1 ,a 2 , … , a n 组成的有限序列,记做 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第  2  章   线 性 表

2.1 线性表的类型定义

2.2 线性表的顺序表示和实现

2.3 线性表的链式表示和实现

2.4 一元多项式的表示及相加

第 2 章 线 性 表

学号 姓名 年龄001 张锦 18

002 李鹏 19

003 林立 19

…… …… ……

100 刘磊 20

Page 2: 第  2  章   线 性 表
Page 3: 第  2  章   线 性 表

2.1 线性表的类型定义

线性表:是 n个类型相同的数据元素的有限序列,数据元素之间是一对一的关系,即每个数据元素最多有一个直接前驱和一个直接后继 。

Page 4: 第  2  章   线 性 表

例 1 英文字母表( A, B, C,…, Z)是一个线性表

例 2

学号 姓名 年龄001 张锦 18

002 李鹏 19

…… …… ……

数据元素

Page 5: 第  2  章   线 性 表

线性表的定义

线性表是由 n (n≥0)个类型相同的数据元素 a1,a2,…, an组成的有限序列,记做( a1,a2,…, ai-1, ai, ai+1, …, an)。n为线性表的长度, n=0时称为空表.线性表的特点同一性:线性表由同类数据元素组成,每一个 ai必须属于同一数据对象。有穷性:线性表由有限个数据元素组成,表长度就是表中数据元素的个数。 n=0时称为空表。有序性:线性表中相邻数据元素之间存在着序偶关系 <ai,ai+1> 。

Page 6: 第  2  章   线 性 表

线性表的抽象数据类型定义ADT  List  {

数据元素: D={ai| ai D0,   i=1,2,…∈ , n ,   n≥0 , D0为某一数据对象 }

关系: R1={ <ai-1,ai> | ai, ai-1 D∈ , i=2, …,n}基本操作:( 1) InitList( &L)操作前提: L为未初始化线性表。操作结果:将 L初始化为空表。( 2) DestroyList(&L)

操作前提:线性表 L已存在。操作结果:将 L销毁。

Page 7: 第  2  章   线 性 表

( 3) ClearList(&L)

操作前提:线性表 L已存在 。操作结果:将表 L置为空表。( 4) EmptyList( L)操作前提:线性表 L已存在。操作结果:如果 L为空表则返回真,否则返回假。( 5) ListLength( L)操作前提:线性表 L已存在。操作结果:如果 L为空表则返回 0,否则返回表中的元素个数。( 6) Locate(L,e)操作前提: 表 L已存在, e为合法元素值。操作结果: 如果 L中存在元素 e,则将“当前指针”指向元素 e所在位置并返回真,否则返回假。

Page 8: 第  2  章   线 性 表

( 7) GetData(L,i)

操作前提:表 L存在,且 i值合法,即 1≤i≤ListLength(L))

操作结果:返回线性表 L中第 i个元素的值。( 8) ListInsert (&L,i,e)

操作前提:表 L已存在, e为合法元素值且 1≤i≤ListLength(L)+1。操作结果:在 L中第 i个位置之前插入新的数据元素 e,L的长度加 1。( 9) ListDelete(&L,i,&e)

操作前提:表 L已存在且非空,  1≤i≤ListLength(L)。操作结果:删除 L的第 i个数据元素,并用 e返回其值,L的长度减 1。}ADT List

Page 9: 第  2  章   线 性 表

2.2 线性表的顺序表示和实现

Page 10: 第  2  章   线 性 表

2.2.1 线性表的顺序存储结构

线性表的顺序存储结构(顺序映像):用一组地址连续的存储单元依次存储线性表的数据元素。

顺序表 : 采用顺序存储结构的线性表通常称为顺序表

Page 11: 第  2  章   线 性 表

内存存储地址 元素序号

备用空间

a1

a2

an

LOC(a1)

LOC(a1) +L

LOC(a1) +(n-1)L

1

2

n

元素地址计算方法:LOC(ai)=LOC(a1)+(i-1)*LLOC(ai+1)=LOC(ai)+L其中:

L—一个元素占用的存储单元个数LOC(ai)—线性表第 i个元素的地址

特点:实现逻辑上相邻—物理地址相邻实现随机存取

Page 12: 第  2  章   线 性 表

顺序存储结构的实现

可以借助于高级程序设计语言中的数组来表示,一维数组的下标与元素在线性表中的序号相对应。

Page 13: 第  2  章   线 性 表

// 线性表的顺序存储结构#define LIST_INIT_SIZE 100 /*

存储空间的初始分配量 */ typedef struct { ElemType elem [LIST_INIT_SIZE];

// 存储空间基址 int length; // 当前长度 }SqList;

以 C语言为例 :

Page 14: 第  2  章   线 性 表

2.2.2 线性表顺序存储结构上的运算 

• 查找• 插入• 删除• 合并

Page 15: 第  2  章   线 性 表

顺序表的查找运算线性表有两种基本的查找运算。按序号查找 GetData(L,i): 要求查找线性表 L中第 i个数据元素,其结果是 L.elem[i-1] 或 L->elem[i-1] 。按内容查找 Locate ( L,e ) : 要求查找线性表L中与给定值 e相等的数据元素,其结果是:若在表 L中找到与 e相等的元素,则返回该元素在表中的序号;若找不到,则返回一个“空序号”,如 -1。

Page 16: 第  2  章   线 性 表

顺序表的查找运算

算法分析:查找运算可采用顺序查找法实现,即从第一个元素开始,依次将表中元素与 e相比较,若相等,则查找成功,返回该元素在表中的序号;若 e与表中的所有元素都不相等,则查找失败,返回“ -1”。 

Page 17: 第  2  章   线 性 表

算法实现:int  Locate(SqList L, ElemType e) {i=0 ;  //i 为计数器 , 从第一个元素开始比较 while ((i<=L.length-1)&&(L.elem[i]!=e) ) /* 顺序扫描表,直到找到值为 e 的元素 , 或扫描到表尾而没找到 */ i++;    if  (i<=L.length-1)         return(i+1);  /* 若找到值为 e 的元素,则返回其序号 */    else            return(-1);  /* 若没找到,则返回空序号 */  }

Page 18: 第  2  章   线 性 表

顺序表的插入运算

定义:在第 i( 1i n+1)个元素前插入一个新的数据元素 e,使长度为 n的线性表(a1, a2,……, ai-1, ai,……, an)

变成长度为 n+1的线性表(a1, a2,……, ai-1, e, ai,……, an)

算法分析:

Page 19: 第  2  章   线 性 表

e

内存

a1

a2

ai

ai+1

an

0

1

i-1

数组下标

n-1

i

n

1

2

i

元素序号

i+1

n

n+1

内存

a1

a2

ai

ai+1

an

0

1

i-1

数组下标

n-1

i

n

1

2

i

元素序号

i+1

n

n+1

an-1

插入 e

Page 20: 第  2  章   线 性 表

算法实现:

Status ListInsert_Sq(Sqlist &L,int i,ElemType e){if(i<1||i>L.length+1) return ERROR;if(L.length>=LIST_INIT_SIZE){ //当前存储已满

return ERROR ;} q=&(L.elem[i-1]); // q为插入位置for(p=&(L.elem[L.length-1]); p>=q; - -p) *(p+

1)=*p; //插入位置之后元素后移 *q=e; ++L.length; return OK;}

Page 21: 第  2  章   线 性 表

算法实现 2:

Status ListInsert_Sq(Sqlist &L,int i,ElemType e){if(i<1||i>L.length+1) return ERROR;if(L.length>=LIST_INIT_SIZE){ //当前存储已满

return ERROR ;}

for(k=L.length-1; k>=i-1; - -k)L.elem[k+1]=L. elem[k]; //插入位置之后元素后移

L.elem[i-1]=e; ++L.length; return OK;}

Page 22: 第  2  章   线 性 表

算法时间复杂度 T(n)

设 Pi是在第 i个元素之前插入一个元素的概率,则在长度为 n的线性表中插入一个元素时,所需移动的元素次数的期望值(平均次数)为:

1

1

)1(n

ii inPEis

nOnT

nin

nEis

nP

n

i

i

1

1 2)1(

1

11

1

若认为

Page 23: 第  2  章   线 性 表

顺序表的删除运算

–定义:线性表的删除是指将第 i( 1i n)个元素删除,使长度为 n的线性表(a1, a2,……, ai-1, ai, ai+1,……, an)

变成长度为 n-1的线性表(a1, a2,……, ai-1,  ai+1, ……, an)

–算法分析:需将第 i+1至第 n共( n-i)个元素前移

Page 24: 第  2  章   线 性 表

内存数组下标 元素序号

0

1

i-1

n-1

i

n

1

2

i

i+1

n

n+1

a1

a2

ai

ai+1

an

ai-1i-2 i-1删除 ai

内存

a1

a2

ai+1

数组下标

0

1

i-1

n-2

i

n-1

1

2

i

元素序号

i+1

n-1

n

an

ai+2

ai-1i-2 i-1

Page 25: 第  2  章   线 性 表

算法实现:

Status ListDelete_Sq(Sqlist &L,int i,ElemType &e){ if(i<1||i>L.length) return ERROR;p=&(L.elem[i-1]); // p 为被删除元素的位置e=*p; // 被删除元素的值赋给 eq=&L.elem[L.length-1]; // 表尾元素的位置for(++p; p<=q; ++p) *(p-1)=*p; // 被删除元素之后的元素左移- -L.length; // 表长减 1 return OK;}

Page 26: 第  2  章   线 性 表

算法实现 2:

Status ListDelete_Sq(Sqlist &L,int i,ElemType &e){

if(i<1||i>L.length) return ERROR;

e= L.elem[i-1]; // 被删除元素的值赋给 efor(k=i; k<=L.length-1; ++k) L.elem[k-1]=L.elem[k]; // 被删除元素之后的元素左移- -L.length; // 表长减 1 return OK;}

Page 27: 第  2  章   线 性 表

算法时间复杂度

设 Qi是删除第 i个元素的概率,则在长度为 n的线性表中删除一个元素所需移动的元素次数的 (期望值)平均次数为:

n

iide inQE

1

)(

nOnT

nin

nE

nQ

n

ide

i

1 2

1)(

1

1

若认为

Page 28: 第  2  章   线 性 表

算法评价:

在顺序表中插入或删除一个元素时,平均移动表的一半元素,当 n很大时,效率很低。

Page 29: 第  2  章   线 性 表

例:顺序表的合并 .有两个顺序表 LA和 LB ,其元素均为非递减有序排列,编写一个算法,将它们合并成一个顺序表 LC,要求 LC 也是非递减有序排列。例如 LA=(2, 2, 3), LB=(1, 3, 3, 4), 则 LC=(1, 2, 2, 3, 3, 3, 4) 。

算法分析 :设表 LC是一个空表,为使 LC也是非递减有序排列,可设两个指针 i、 j分别指向表 LA和 LB 中的元素,若 LA.elem[i]>LB.elem[j] ,则当前先将 LB.elem[j] 插入到表 LC中,若 LA.elem[i]≤LB.elem[j] ,当前先将 LA.elem[i] 插入到表 LC中,如此进行下去,直到其中一个表被扫描完毕,然后再将未扫描完的表中剩余的所有元素放到表 LC中。

Page 30: 第  2  章   线 性 表

算法模拟

2

2

3

1

3

3

4

下标下标 下标LA

值 值值LB LC

0

2

1

0

1

2

0

1

2

3

4

5

6

i j k12

2

3

3

3

43

i

i

j

j

j

j

i

k

k

k

k

k

k

k

Page 31: 第  2  章   线 性 表

算法实现 :void   merge(SqList LA,  SqList LB,  SqList &LC)  {  i=0;j=0;k=0;   while(i<=LA.length-1&&j<=LB.length-1)     if(LA.elem[i]<=LB.elem[j]) {        LC.elem[k]= LA.elem[i];    i++; k++;  }         else        { LC.elem[k]=LB.elem[j];    j++; k++;     }     while(i<=LA.length-1)      /* 当表 LA有剩余元素时,则将

表 LA余下的元素赋给表 LC*/     {   LC.elem[k]= LA.elem[i];  i++; k++;     }     while(j<=LB.length-1)  /* 当表 LB 有剩余元素时,则将表

LB余下的元素赋给表 LC*/      {   LC.elem[k]= LB.elem[j];    j++;  k++;    }        LC.length=LA.length+LB.length;   }

Page 32: 第  2  章   线 性 表

顺序存储结构的优缺点:

优点逻辑相邻,物理相邻可随机存取任一元素

缺点插入、删除操作需要移动大量的元素

Page 33: 第  2  章   线 性 表

特点:•用一组任意的存储单元存储线性表的数据元素•利用指针实现了用不相邻的存储单元存放逻辑上相邻的元素•每个数据元素 ai,除存储本身信息外,还需存储其直接后继的信息•结点–数据域:元素本身信息–指针域:指示直接后继的存储位置

数据域  指针域结点

2.3 线性表的链式存储结构

Page 34: 第  2  章   线 性 表

ZHAO QIAN SUN LI

ZHOU WU ZHENG WANG ^

H

例 线性表 (ZHAO,QIAN,SUN,LI,ZHOU,WU,ZHENG,WANG)

43

13

1

NULL3771925

数据域 指针域

LI

QIAN

SUN

WANGWU

ZHAOZHENG

ZHOU

存储地址

17

131925313743

31H

头指针

Page 35: 第  2  章   线 性 表

• 实现 typedef struct LNode { ElemType data; struct LNode *next;}LNode,*LinkList;

LinkList L,p;

data next

p 结点( *p)

(*p)表示 p所指向的结点(*p).datap->data表示 p指向结点的数据域(*p).nextp->next表示 p指向结点的指针域

生成一个 LNode型新结点: p=(LinkList)malloc(sizeof(LNode));系统回收 p结点: free(p)

2.3.1 线性链表• 定义:结点中只含一个指针域的链表叫 ~,也叫单链表

Page 36: 第  2  章   线 性 表

L a1 a2

头结点头结点an ^…...…...

L 空表^̂

头结点:在单链表第一个结点前附设一个结点叫头结点 .头结点指针域为空表示线性表为空

第一个数据元素的值 :L->next->data第二个数据元素的指针 :L->next->next

p

p->datap->nextp->next->datap->next->next

Page 37: 第  2  章   线 性 表

1. 头插法建立单链表2. 尾插法建立单链表3. 查找4. 插入5. 删除

单链表的基本运算

Page 38: 第  2  章   线 性 表

1. 头插法建立单链表算法描述 :逆位序输入 n个元素的值 ,建立带头结点的单链表算法演示 :如输入二个元素 a,b,头插法建立单链表

L ^ a

b

^

p

p

Page 39: 第  2  章   线 性 表

1. 头插法建立单链表算法实现 :void CreateList_L(LinkList &L,int n){L=(LinkList)malloc(sizeof(LNode));L->next=NULL;//先建立一个带头结点的单链表for(i=n;i>0;--i){p=(LinkList)malloc(sizeof(LNode));//生成新结点scanf(&p->data);//输入元素值p->next=L->next;L->next=p;// 插入到表头}}

Page 40: 第  2  章   线 性 表

2. 尾插法建立单链表算法描述 :正位序输入 n个元素的值 ,建立带头结点的单链表算法演示 :如输入二个元素 a,b, 尾插法建立单链表

L ^

p

a

r

b^

r

Page 41: 第  2  章   线 性 表

2. 尾插法建立单链表算法实现 :void CreateList_L2(LinkList &L,int n){L=(LinkList)malloc(sizeof(LNode));L->next=NULL;//先建立一个带头结点的单链表r=L;//r为表尾元素指针for(i=n;i>0;--i){p=(LinkList)malloc(sizeof(LNode));//生成新结点scanf(&p->data);//输入元素值p->next=NULL;r->next=p;r=p; // 插入到表尾}}

Page 42: 第  2  章   线 性 表

3. 查找

• 按序号查找• 按值查找

Page 43: 第  2  章   线 性 表

按序号查找

算法描述 : 设带头结点的单链表的头指针为 L,要查找表中第 i个结点 ,则需从单链表的头指针 L出发 , 从头结点开始 ,顺着链域扫描 .用指针 p指向当前扫描到的结点 ,初值指向第一个结点 (p=L->next). 用 j做计数器 ,累计当前扫描过的结点数 (初值为 1), 当 j=i 时 ,指针 p所指的结点就是要找的第 i个结点 .

Page 44: 第  2  章   线 性 表

算法演示

Status GetElem_L(LinkList L,int i,ElemType &e)

{p=L->next;j=1;

while(p&&j<i){

p=p->next;++j;}

if(!p||j>i)

return ERROR;

e=p->data;

return OK;}

L

a

b

m

n

……

……

i

p

^

Page 45: 第  2  章   线 性 表

按值查找

Page 46: 第  2  章   线 性 表

算法演示

LinkList Locate_L(LinkList L,ElemType e)}

p=L->next;

while(p){

if(p->data==e)

break;

else

p=p->next;}

return p;}

L

a

b

e

n

……

……

p

^

Page 47: 第  2  章   线 性 表

p a b

xs

插入:在线性表两个数据元素 a和 b间插入 x,已知 p指向 a

s->next=p->next;p->next=s;

1OnT

算法评价

4. 插入

Page 48: 第  2  章   线 性 表

算法实现

Status ListInsert_L(ListList &L,int I,ElemType e){// 在带头结点的单链表 L中第 i个位置之前插入元素 e

p=L;j=0;while(p&&j<i-1){p=p->next;++j;}// 寻找第 i-1个结点if(!p||j>i-1) return ERROR;s=(LinkList)malloc(sizeof(LNode));// 生成新结点s->data=e;s->next=p->next;p->next=s;return OK;}

Page 49: 第  2  章   线 性 表

p a b c

1OnT

算法评价

–删除:单链表中删除 b,设 p指向 a

p->next=q->next;

5. 删除

q

Page 50: 第  2  章   线 性 表

算法实现Status ListDelete_L(ListList &L,int I,ElemType

&e){// 在带头结点的单链表 L 中删除第 i 个元素,由 //e 返回其值

p=L;j=0;

while(p->next&&j<i-1){p=p->next;++j;}// 寻找第 i-1 个结点

if(!(p->next)||j>i-1) return ERROR;

q=p->next;p->next=q->next;

e=q->data;free(q);

return OK;

}

Page 51: 第  2  章   线 性 表

例 :将两个有序链表并为一个有序链表

算法描述 : 设头指针 La和 Lb的单链表分别为线性表 LA和 LB 的存储结构 ,现要归并 La和 Lb 得到单链表 Lc.需设立 3个指针 pa,pb和 pc, 其中 pa 和 pb分别指向 La 表和 Lb表中当前待比较插入的结点 ,而 pc 指向 Lc 表中当前最后一个结点 .若 pa->data<=pb->data, 则将 pa 所指结点链接到 pc 所指结点之后 ,否则将 pb所指结点链接到 pc 所指结点之后 ,直到 La或 Lb 链表为空,则将另一个链表的剩余段链接在 pc 所指结点之后即可。

Page 52: 第  2  章   线 性 表

算法演示

La

Lb

pa

pb

pcLc

2 2 3

4331

^

^

Page 53: 第  2  章   线 性 表

算法实现void MergeList_L(LinkList La, Lb,&Lc){

pa=La->next;pb=Lb->next;

Lc=pc=La;

while(pa&&pb){

if(pa->data<=pb->data){

pc->next=pa;pc=pa;pa=pa->next;}

else{pc->next=pb;pc=pb;pb=pb->next;}

}

pc->next=pa?pa:pb;

free(Lb);}

Page 54: 第  2  章   线 性 表

• 单链表特点–它是一种动态结构,整个存储空间为多个链表共用

–不需预先分配空间–指针占用额外存储空间–不能随机存取,查找速度慢

Page 55: 第  2  章   线 性 表

循环链表是表中最后一个结点的指针指向头结点,使链表构成环状•特点:从表中任一结点出发均可找到表中其他结点,提高查找效率•操作与单链表基本一致 ,循环条件不同–单链表 p 或 p->next=NULL–循环链表 p=H 或 p->next=H

H

H 空表

2.3.2 循环链表

Page 56: 第  2  章   线 性 表

单链表具有单向性的缺点• 结点定义

typedef struct DuLNode { ElemType data; struct DuLNode *prior,*next;} DuLNode,*DuLinkList;

prior data next

L空双向循环链表:

非空双向循环链表:L A B

b ca

p

p->prior->next= p= p->next->proir

2.3.3 双向链表

Page 57: 第  2  章   线 性 表

查找操作

算法描述 : 在带头结点的双循环链表L中查找第 i个位置的元素 ,找到则返回该元素的指针 ,否则返回空指针

Page 58: 第  2  章   线 性 表

算法演示

DuLinkList GetElem_Du(DuLinkList L,int i)

{p=L->next;j=1;

while(p!=L&&j<i){

p=p->next;++j;}

if(p==L)

p=NULL;

return p;

}

L

a

b

m

n

……

……

i

p

Page 59: 第  2  章   线 性 表

b c

void del_dulist(DuLinkList p){p->prior->next=p->next; p->next->prior=p->prior; free(p);}

– 算法描述

– 算法评价: T(n)=O(1)

p->prior->next=p->next;

p->next->prior=p->prior;

删除操作

a

p

Page 60: 第  2  章   线 性 表

void ins_dulist(DuLinkList p,int x){ s=(DuLinkList)malloc(sizeof(DuLNode)); s->data=x; s->prior=p->prior; p->prior->next=s; s->next=p; p->prior=s;}

算法描述

算法评价:T(n)=O(1)

xS

ba

P插入操作

Page 61: 第  2  章   线 性 表

一元多项式的表示:

200001000 231)( xxxS 但对 S(x)这样的多项式浪费空间

其存储结构可以用顺序存储结构,也可以用单链表

2.4 一元多项式的表示及相加

nnn xPxPxPPxP 2

210)( ……

),,,,( 210 nPPPPP 可用线性表 P表示 ……

用数据域含两个数据项的线性表表示

emPePeP m,,,,, 21 21 …

一般 emmn xPxPxPxP ee 21

21)(

其中 为非零系数)( iPemee 210 …

……

Page 62: 第  2  章   线 性 表

单链表的结点定义

coef exp next

-1A 7 0 3 1 9 8 5 17 ^

-1B 8 1 22 7 -9 8 ^

-1C 7 0 11 1 22 7 5 17 ^

一元多项式相加

typedef struct node{int codf,exp;struct node *next}node,*linklist;

177

87

172

522117)()()(

9228)(

5937)(

xxxxBxAxC

xxxxB

xxxxA

8

Page 63: 第  2  章   线 性 表

设p,q 分别指向 A,B中某一结点,p,q 初值是第一结点

比较p->exp与 q->exp

p->exp < q->exp: p结点是和多项式中的一项              p后移 ,q不动p->exp > q->exp: q结点是和多项式中的一项             将 q插在 p之前 ,q后移 ,p不动p->exp = q->exp: 系数相加 0:从 A表中删去 p,

            释放 p,q, p,q后移

0:修改 p系数域 ,            释放 q, p,q后移

直到 p或 q为 NULL  若 q==NULL,结束 若 p==NULL,将 B中剩余部分连到 A上即可

运算规则

Page 64: 第  2  章   线 性 表

q

-1pa 7 0 3 1 9 8 5 17 ^

-1pb 8 1 22 7 -9 8 ^

ppre

q

-1pa 7 0 3 1 9 8 5 17 ^

-1pb 8 1 22 7 -9 8 ^

ppre

q

-1pa 7 0 11 1 9 8 5 17 ^

-1pb 8 1 22 7 -9 8 ^

p

preq

-1pa 7 0 11 1 9 8 5 17 ^

-1pb 8 1 22 7 -9 8 ^

ppre

q=NULL

-1pa 7 0 11 1 9 8 5 17 ^

-1pb 8 1 22 7 -9 8 ^

p

pre

q=NULL

-1pa 7 0 11 1 9 8 5 17 ^

-1pb 8 1 22 7 -9 8 ^

p

pre

-1pa 7 0 11 1 22 7 5 17 ^

–算法描述