线性表的应用
前言
一、线性表的合并
-
问题描述:
假设利用两个线性表 La和 Lb分别表示两个集合A和B,先要求一个新的集合 A=A∪B
-
算法思想:
依次取出 Lb中的每个元素,执行以下操作:
在 La中查找该元素,如果找不到,则将其插入 La的最后 -
算法描述:
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(ListLength(LA)*ListLength(LB))
二、有序表的合并
1.顺序表
- 问题描述:
已知线性表La 和Lb中的数据元素按值非递减有序排列,现要求将La和Lb归并为一个新的线性表Lc,且Lc中的数据元素仍按值非递减有序排列
如:
La=(1,6,7)
Lb=(2,3,4,5,6,7,11)
则Lc=(1,2,3,4,5,6,6,7,7,11) - 算法思想:
- 创建一个空表Lc;
- 依次从La或Lb中摘取元素值较小的结点插入到Lc表的最后,直到一个表为空;
- 继续将La或Lb中剩余的一个表的剩下的元素插入在Lc表的末尾。
- 算法描述:
void MergeList_Sq(SqList LA,SqList LB,SqList &LC){
int i=0,j=0,k=0; /*所有值都指向第一个元素*/
LC.length = LA.length + LB.length; /*新表的长度为LA与LB长度之和*/
LC.elem = new ElemType[Lc.length]; /*为合并后的新表申请一个空间*/
while(i<LA.length && j<LB.length){ /*两表都非空*/
if(LA.elem[i]<=LB.elem[j])
LC.elem[k++]=LA.elem[i++];
else
LC.elem[k++]=LB.elem[j++];
} /*取元素*/
while(i<LA.length)
LC.elem[k++] = LA.elem[i++]; /*将LA中的剩余元素插入LC*/
while(i<LB.length)
LC.elem[k++] = LB.elem[j++]; /*将LB中的剩余元素插入LC*/
}
- 算法分析:
T(n)=S(n)=O(ListLength(A)+ListLength(B))
2.链表⭐⭐
-
问题描述:
将La,Lb两个有序链表合并成一个有序的单链表Lc
结果链仍使用原来两个链表的空间,不另外占用其他的存储空间 -
算法思想:
(1). Lc指向La;
(2).依次从La或Lb中摘取值较小的结点插入到Lc的末尾,直到一个链表为空;
(3).继续将La或Lb其中一个表的剩余结点插入到Lc的末尾;
(4).释放Lb的表头结点; -
图示理解:
初始化
pa ->data <= pb->data
pa->data > pb->data
一个链表成空
合并完成
-
算法描述:
void MergeList_L(LinkList &La,LinkList&Lb,LinkList &Lc){
LNode *pa,*pb,*pc;
pa = La->next; pb = Lb->next;
pc = Lc = La; /*用La的头结点作为Lc的头结点*/
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; /*释放Lb头结点*/
}
- 算法分析:
T(n)=O(ListLength(LA)+ListLength(LB));
S(n)=O(1);
三、一元多项式的表示及相加
用线性表表示多项式一般采用存储非零系数与相应指数的方法:
P(x) = p1 * x^e1 + p2 * x^e2 + … + pm * x ^ em
表示为:((p1,e1),(p2,e2),…,(pm,em))
1.顺序结构
- 结构定义
typedef struct{
double coef;
int exp;
}ElemType;
typedef struct{
ElemType *elem;
int length;
int MaxSize;
}SqList;
- 多项式求值算法
double PolySum(SqList &P,double x){
double sum = 0;
int e;
for(int i=0; i < P.length;i++){
e = P.elem[i].exp;
sum = sum + P.elem[i].coef*pow(x,e);
}
return sum;
}
2.链式结构
- 结构定义
typedef struct{
double coef;
int exp;
}ElemType;
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
- 多项式求值算法
double PolySum(LinkList *P,double x){
LNode *t = P->next;
double sum = 0;
int e;
while(t!=NULL){
e = t.data.exp;
sum = sum + t->data.coef*pow(x,e);
t = t->next;
}
return sum;
}
- 多项式相加
指数相同:相加,若和不为0,构成一项。
指数不同:复制到多项式中。
算法实现:
void AddPoly(LinkList &Pa,LinkList &Pb){
LNode *p1 = Pa->next,*p2 = Pb->next,*p3=Pa,*r;
double sum;
while(p1 && p2){
if(p1->data.exp < p2->data.exp){
p3->next = p1; p3 = p1;
p1 = p1->next;
}
else if(p1->data.exp > p2->data.exp){
p3->next = p2; p3 = p2;
p2 = p2->next;
}
else{
sum = p1->data.coef + p2->data.coef;
if(sum!=0){
p1->data.coef = sum;
p3->next = p1;
p3 = p1;
p1 = p1->next;
r = p2; p2 = p2->next; delete r;
}
else{
r = p1; p1 = p1->next; delete r;
r = p2; p2 = p2->next; delete r;
}
}
}//while
p3->next = p1?p1:p2;
delete Pb;
}