线性表的应用
线性表的合并
- 问题描述:
假设利用两个线性表
L
a
L_a
La?和
L
b
L_b
Lb?分别表示两个集合
A
A
A和
B
B
B,现要求一个新集合
A
=
A
∪
B
A=A∪B
A=A∪B
L
a
=
(
7
,
5
,
3
,
11
)
L_a=(7,5,3,11)
La?=(7,5,3,11)
L
b
=
(
2
,
6
,
5
)
L_b=(2,6,5)
Lb?=(2,6,5)
?
>
->
?>
L
a
=
(
7
,
5
,
3
,
11
,
2
,
6
)
L_a=(7,5,3,11,2,6)
La?=(7,5,3,11,2,6)
void union(List &La,List &Lb){
La_len=ListLength(La);
Lb_len=ListLength(Lb);
for(int i=1;i<=Lb_len;i++){
GetElem(Lb,i,e);
if(!LocateElem(La,e)) ListInsert(&La,++La_len,e);
}
}
- 时间复杂度:
O
(
L
a
_
l
e
n
)
?
O
(
L
b
_
l
e
n
)
O(La\_len)*O(Lb\_len)
O(La_len)?O(Lb_len)
- 空间复杂度:
O
(
L
a
_
l
e
n
)
?
O
(
L
b
_
l
e
n
)
O(La\_len)*O(Lb\_len)
O(La_len)?O(Lb_len)
有序表的合并
- 问题描述:
已知线性表
L
a
L_a
La?和
L
b
L_b
Lb?中的数据元素按值非递减有序排列,现要求将
L
a
L_a
La?和
L
b
L_b
Lb?归并为新的线性表
L
c
L_c
Lc?,且
L
c
L_c
Lc?中的数据元素仍按值非递减有序排列。
L
a
=
(
1
,
7
,
8
)
L_a=(1,7,8)
La?=(1,7,8)
L
b
=
(
2
,
4
,
6
,
8
,
10
,
11
)
L_b=(2,4,6,8,10,11)
Lb?=(2,4,6,8,10,11)
?
>
->
?>
L
a
=
(
1
,
2
,
4
,
6
,
7
,
8
,
8
,
10
,
11
)
L_a=(1,2,4,6,7,8,8,10,11)
La?=(1,2,4,6,7,8,8,10,11)
- 算法步骤
1.创建一个空表
L
c
L_c
Lc? 2.一次从
L
a
L_a
La?或
L
b
L_b
Lb?中“摘取”元素值较小的元素插入到
L
c
L_c
Lc?表的最后,直至其中一个表变空为止 3.继续将
L
a
L_a
La?或
L
b
L_b
Lb?其中一个表的剩余结点插入在
L
c
L_c
Lc?表的最后
顺序表实现
void MergeList_Sq(SqList LA,SqList LB,SqList &LC){
pa=LA.elem;
pb=LB.elem;
LC.length=LA.length+LB.length;
LC.elem=new ElemType[LC.length];
pc=LC.elem;
pa_last=LA.elem+LA.length-1;
pb_last-LB.elem+LB.length-1;
while(pa<=pa_last&&pb<=pb_last){
if(*pa<=*pb)*pc++=*pa++;
else *pc++=*pb++;
}
while(pa<=pa_last) *pc++=*pa++;
while(pb<=pb_last) *pc++=*pb++;
}
- 时间复杂度:
O
(
L
i
s
t
L
e
n
g
t
h
(
L
a
)
+
L
i
s
t
L
e
n
g
t
h
(
L
b
)
)
O(ListLength(La)+ListLength(Lb))
O(ListLength(La)+ListLength(Lb))
- 空间复杂度:
O
(
L
i
s
t
L
e
n
g
t
h
(
L
a
)
+
L
i
s
t
L
e
n
g
t
h
(
L
b
)
)
O(ListLength(La)+ListLength(Lb))
O(ListLength(La)+ListLength(Lb))
链表实现
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){
LinkList pa,pb,pc;
pa=La->next;pb=Lb->next;
pc=Lc=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; delete Lb;
}
- 时间复杂度:
O
(
L
i
s
t
L
e
n
g
t
h
(
L
a
)
+
L
i
s
t
L
e
n
g
t
h
(
L
b
)
)
O(ListLength(La)+ListLength(Lb))
O(ListLength(La)+ListLength(Lb))
- 空间复杂度:
O
(
1
)
O(1)
O(1)
案列(2.1)一元多项式的运算
例如:
P
a
(
x
)
=
10
+
5
x
?
4
x
2
+
3
x
3
+
2
x
4
P_a(x)=10+5x-4x^2+3x^3+2x^4
Pa?(x)=10+5x?4x2+3x3+2x4
P
b
(
x
)
=
?
3
+
8
x
+
4
x
2
?
5
x
4
+
7
x
5
?
2
x
6
P_b(x)=-3+8x+4x^2-5x^4+7x^5-2x^6
Pb?(x)=?3+8x+4x2?5x4+7x5?2x6
加法运算
void add_Sq(List &La,list &Lb){
for(int i=0;i<max(La.length,Lb.length);i++){
La.elem[i]+=Lb.elem[i];
}
}
案例(2.2)稀疏多项式运算
线性表A=((7,0),(3,1),(9,8),(5,17)) 线性表B=((8,1),(22,7),(9,8)) 注:(a,b):a:系数;b:指数
顺序表实现
- 算法步骤:
1.创建一个数组c 2.分别从头遍历比较a和b的每一项 指数相同,对应系数相加,若其和不为零,则在c中增加一个新项 指数相同,则将指数较小的项复制到c中 3.一个多项式已遍历完毕时,将另一个剩余项依次复制到c中即可
实现问题:c数组空间大小、运算空间复杂度高 解决办法:链式存储
链表实现
链式存储结构创建多项式:
typedef struct PNode{
float coef;
int expn;
struct PNode *next;
}PNode,*Polynomial;
void CreatePolyn(Polynmial &P,int i){
P=new PNode;
p->next=NULL;
for(int i=1;i<=n;i++){
s=new PNode;
cin>>s->coef>>s->expn;
pre=P;
q=P->next;
while(q&&q->expn<s->expn){
pre=q;q=q->next;
}
s->next=q;
pre->next=s;
}
}
链式多项式的相加运算
- 算法步骤
1.指针p1和p2初始化,分别指向pa和pb的首元节点 2.p3指向和多项式的当前节点,初值为pa的头结点 3.当指针p1和p2均未到达表尾时,则循环比较p1和p2所指结点对应的指针值 (p1->expn与p2->expn),有下列3种情况 (1)当p1->expn=p2->expn时,则将两个结点中的系数相加 若和不为零,则修改p1所指结点的系数值,同时删除p2所指结点 若和为零,则删除p1和p2所指结点 (2)当p1->expnexpn时,则应摘取p1所指点插入到“和多项式”链表中去 (3)当p1->expn>2->expn时,则应摘取p2指结点插入到“和多项式”链表中去 4.将非空多项式的剩余段插入到p3所指结点之后 5.释放pb的头结点
|