例2-1
利用两个线性表LA和LB分别表示两个集合A和B,现要求一个新的集合A=A∪B。
本例是将两个表合并到A中,并且A,B中元素可能非有序
// algo2-1.cpp 实现算法2.1的程序
#include"c1.h"
typedef int ElemType;
#include"c2-1.h" // 采用线性表的动态分配顺序存储结构
#include"bo2-1.cpp" // 可以使用bo2-1.cpp中的基本操作
Status equal(ElemType c1,ElemType c2)
{ // 判断是否相等的函数,Union()用到
if(c1==c2)
return TRUE;
else
return FALSE;
}
void Union(SqList &La,SqList
Lb) // 算法2.1
{ // 将所有在线性表Lb中但不在La中的数据元素插入到La中
ElemType e;
int La_len,Lb_len;
int i;
La_len=ListLength(La); //
求线性表的长度
Lb_len=ListLength(Lb);
for(i=1;i<=Lb_len;i++)
{
GetElem(Lb,i,e); // 取Lb中第i个数据元素赋给e
if(!LocateElem(La,e,equal)) // La中不存在和e相同的元素,则插入之,LocateElem时间复杂度o(La_len)
ListInsert(La,++La_len,e);
}
}
void print(ElemType
&c)
{
printf("%d ",c);
}
void main()
{
SqList La,Lb;
Status i;
int j;
i=InitList(La);
if(i==1) // 创建空表La成功
for(j=1;j<=5;j++) // 在表La中插入5个元素
i=ListInsert(La,j,j);
printf("La= "); //
输出表La的内容
ListTraverse(La,print);
InitList(Lb); //
也可不判断是否创建成功
for(j=1;j<=5;j++) // 在表Lb中插入5个元素
i=ListInsert(Lb,j,2*j);
printf("Lb= "); //
输出表Lb的内容
ListTraverse(Lb,print);
Union(La,Lb);
printf("new La= "); //
输出新表La的内容
ListTraverse(La,print);
}
-------------------------------------------------
// algo2-12.cpp 用单链表实现算法2.1,仅有4句与algo2-1.cpp不同
#include"c1.h"
typedef int ElemType;
#include"c2-2.h" //
此句与algo2-1.cpp不同(因为采用不同的结构)
#include"bo2-2.cpp"
// 此句与algo2-1.cpp不同(因为采用不同的结构)
void Union(LinkList La,LinkList Lb)
// 算法2.1,此句与algo2-1.cpp不同
{ // 将所有在线性表Lb中但不在La中的数据元素插入到La中
...
}
void main()
{
LinkList La,Lb; //
此句与algo2-1.cpp不同(因为采用不同的结构)
...
}
--------------------------------------------------------------------------------------------
例2-2 巳知线性表LA和线性表LB中的数据元素按值非递减有序排列,现要求将LA和LB归并为一个新的线性表LC,且LC中的元素仍按值非递减有序排列。
// algo2-2.cpp 实现算法2.2的程序
#include"c1.h"
typedef int ElemType;
#include"c2-1.h"
#include"bo2-1.cpp"
void MergeList(SqList La,SqList Lb,SqList
&Lc) // 算法2.2
{ // 已知线性表La和Lb中的数据元素按值非递减排列。
//
归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列
int i=1,j=1,k=0;
int La_len,Lb_len;
ElemType ai,bj;
InitList(Lc); // 创建空表Lc
La_len=ListLength(La);
Lb_len=ListLength(Lb);
while(i<=La_len&&j<=Lb_len)
// 表La和表Lb均非空
{
GetElem(La,i,ai);
GetElem(Lb,j,bj);
if(ai<=bj)
{
ListInsert(Lc,++k,ai);//1≤k≤ListLength(L)+1,在第k个位置插入,ListInsert会减一作为插入位置
++i;
}
else
{
ListInsert(Lc,++k,bj);
++j;
}
}
while(i<=La_len) // 表La非空且表Lb空
{
GetElem(La,i++,ai);
ListInsert(Lc,++k,ai);
}
while(j<=Lb_len) // 表Lb非空且表La空
{
GetElem(Lb,j++,bj);
ListInsert(Lc,++k,bj);
}
}
void print(ElemType
&c)
{
printf("%d ",c);
}
void main()
{
SqList La,Lb,Lc;
int
j,a[4]={3,5,8,11},b[7]={2,6,8,9,11,15,20};
InitList(La); // 创建空表La
for(j=1;j<=4;j++) // 在表La中插入4个元素
ListInsert(La,j,a[j-1]);
printf("La= "); //
输出表La的内容
ListTraverse(La,print);
InitList(Lb); // 创建空表Lb
for(j=1;j<=7;j++) // 在表Lb中插入7个元素
ListInsert(Lb,j,b[j-1]);
printf("Lb= "); //
输出表Lb的内容
ListTraverse(Lb,print);
MergeList(La,Lb,Lc);
printf("Lc= "); //
输出表Lc的内容
ListTraverse(Lc,print);
}
http://s5/middle/690e573948f6aae917df4&690两个线性表合并的问题" TITLE="第二章 两个线性表合并的问题" />
-----------------------------------------------------------------
// algo2-13.cpp
采用链表结构实现算法2.2的程序,仅有4句与algo2-2.cpp不同
#include"c2-2.h" //
此句与algo2-2.cpp不同
#include"bo2-2.cpp" // 此句与algo2-2.cpp不同
void MergeList(LinkList La,LinkList
Lb,LinkList &Lc) // 算法2.2,此句与algo2-2.cpp不同
{
....
}
void main()
{
LinkList La,Lb,Lc; //
此句与algo2-2.cpp不同
...
}
------------------------------------------------------------------------------------------------
与算法2.2的区别在于本例使用了指针,而没用GetElem(La,i,ai)
// algo2-3.cpp 实现算法2.7的程序
#include"c1.h"
typedef int ElemType;
#include"c2-1.h"
#include"bo2-1.cpp"
void MergeList(SqList La,SqList Lb,SqList
&Lc) // 算法2.7
{ // 已知顺序线性表La和Lb的元素按值非递减排列。
//
归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列
ElemType
*pa,*pa_last,*pb,*pb_last,*pc;
pa=La.elem;
//直接用指针获取表La的首地址
pb=Lb.elem;
Lc.listsize=Lc.length=La.length+Lb.length;//不用InitList()创建空表Lc
pc=Lc.elem=(ElemType
*)malloc(Lc.listsize*sizeof(ElemType));
if(!Lc.elem) // 存储分配失败
exit(OVERFLOW);
pa_last=La.elem+La.length-1;
pb_last=Lb.elem+Lb.length-1;
while(pa<=pa_last&&pb<=pb_last)
// 表La和表Lb均非空
{ // 归并
if(*pa<=*pb)
*pc++=*pa++;
else
*pc++=*pb++;
}
while(pa<=pa_last) // 表La非空且表Lb空
*pc++=*pa++; // 插入La的剩余元素
while(pb<=pb_last) // 表Lb非空且表La空
*pc++=*pb++; // 插入Lb的剩余元素
}
void print(ElemType
&c)
{
printf("%d ",c);
}
void main()
{
SqList La,Lb,Lc;
int j;
InitList(La); // 创建空表La
for(j=1;j<=5;j++) // 在表La中插入5个元素
ListInsert(La,j,j);
printf("La= "); //
输出表La的内容
ListTraverse(La,print);
InitList(Lb); // 创建空表Lb
for(j=1;j<=5;j++) // 在表Lb中插入5个元素
ListInsert(Lb,j,2*j);
printf("Lb= "); //
输出表Lb的内容
ListTraverse(Lb,print);
MergeList(La,Lb,Lc);
printf("Lc= "); //
输出表Lc的内容
ListTraverse(Lc,print);
}
// algo2-4.cpp 修改算法2.7的第一个循环语句中的条件语句为开关语句,且当
// *pa=*pb时,只将两者中之一插入Lc。此操作的结果和算法2.1相同
#include"c1.h"
typedef int ElemType;
#include"c2-1.h"
#include"bo2-1.cpp"
int comp(ElemType c1,ElemType c2)
{
int i;
if(c1<c2)
i=1;
else if(c1==c2)
i=0;
else
i=-1;
return i;
}
void MergeList(SqList La,SqList Lb,SqList
&Lc)
{ // 另一种合并线性表的方法(根据算法2.7下的要求修改算法2.7)
ElemType
*pa,*pa_last,*pb,*pb_last,*pc;
pa=La.elem;
pb=Lb.elem;
Lc.listsize=La.length+Lb.length; // 此句与算法2.7不同
pc=Lc.elem=(ElemType *)malloc(Lc.listsize*sizeof(ElemType));
if(!Lc.elem)
exit(OVERFLOW);
pa_last=La.elem+La.length-1;
pb_last=Lb.elem+Lb.length-1;
while(pa<=pa_last&&pb<=pb_last)
// 表La和表Lb均非空
switch(comp(*pa,*pb)) // 此句与算法2.7不同
{
case 0: pb++;
case 1: *pc++=*pa++;
break;
case -1: *pc++=*pb++;
}
while(pa<=pa_last) // 表La非空且表Lb空
*pc++=*pa++;
while(pb<=pb_last) // 表Lb非空且表La空
*pc++=*pb++;
Lc.length=pc-Lc.elem; //
加此句
}
void print(ElemType
&c)
{
printf("%d ",c);
}
void main()
{
SqList La,Lb,Lc;
int j;
InitList(La); // 创建空表La
for(j=1;j<=5;j++) // 在表La中插入5个元素
ListInsert(La,j,j);
printf("La= "); //
输出表La的内容
ListTraverse(La,print);
InitList(Lb); // 创建空表Lb
for(j=1;j<=5;j++) // 在表Lb中插入5个元素
ListInsert(Lb,j,2*j);
printf("Lb= "); //
输出表Lb的内容
ListTraverse(Lb,print);
MergeList(La,Lb,Lc);
printf("Lc= "); //
输出表Lc的内容
ListTraverse(Lc,print);
}
-------------------------------------
// algo2-5.cpp 实现算法2.11、2.12的程序
#include"c1.h"
typedef int ElemType;
#include"c2-2.h"
#include"bo2-2.cpp"
void CreateList(LinkList
&L,int n) //
算法2.11 时间复杂度o(n)
{ // 逆位序(插在表头)输入n个元素的值,建立带表头结构的单链线性表L
int i;
LinkList p;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
// 先建立一个带头结点的单链表
printf("请输入%d个数据\n",n);
for(i=n;i>0;--i)
{
p=(LinkList)malloc(sizeof(LNode)); // 生成新结点
scanf("%d",&p->data); // 输入元素值
p->next=L->next; // 插入到表头
L->next=p;
}
}
void CreateList2(LinkList
&L,int n)
{ // 正位序(插在表尾)输入n个元素的值,建立带表头结构的单链线性表
int i;
LinkList p,q;
L=(LinkList)malloc(sizeof(LNode)); // 生成头结点
L->next=NULL;
q=L;
printf("请输入%d个数据\n",n);
for(i=1;i<=n;i++)
{
p=(LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);
q->next=p;
q=q->next;
}
p->next=NULL;
}
void MergeList(LinkList La,LinkList
&Lb,LinkList &Lc)// 算法2.12
{ // 已知单链线性表La和Lb的元素按值非递减排列。
//
归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列
LinkList
pa=La->next,pb=Lb->next,pc;
Lc=pc=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; // 插入剩余段
free(Lb); // 释放Lb的头结点
Lb=NULL;
}
void visit(ElemType c) //
ListTraverse()调用的函数(类型要一致)
{
printf("%d ",c);
}
void main()
{
int n=5;
LinkList La,Lb,Lc;
printf("按非递减顺序, ");
CreateList2(La,n); //
正位序输入n个元素的值
printf("La="); //
输出链表La的内容
ListTraverse(La,visit);
printf("按非递增顺序, ");
CreateList(Lb,n); //
逆位序输入n个元素的值
printf("Lb="); //
输出链表Lb的内容
ListTraverse(Lb,visit);
MergeList(La,Lb,Lc); //
按非递减顺序归并La和Lb,得到新表Lc
printf("Lc="); //
输出链表Lc的内容
ListTraverse(Lc,visit);
}
加载中,请稍候......