|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 兔子不吃窝边草 于 2021-10-2 16:39 编辑
已知线性表La,Lb的数据元素是升序排列。将La与Lb合并为一个新的表Lc,Lc中的数据元素也是升序排列。La=(3,5,8,11),Lb=(2,6,8,9,11,15,20)
求出来的Lc=(2,3,5,6,8,9,11,11,15,20)
动态数组的插入ListInsert(),加入了判断是否满的情况,因此不用担心溢出的问题。
#include<stdio.h>
#include<stdlib.h>
#define ListInitsize 20//初始分配内存数
#define OVERFLOW -2 //异常状态
#define ADD 10 //分配内存增量
typedef struct
{
int *data;//顺序线性表动态数组名
int length;//线性表长度
int Listsize;//线性表当前分配的内存数量;
}List;
int InitList(List *L)//线性表初始化
{
L->data =malloc(ListInitsize*sizeof(int));//分配内存
if(!L->data)
exit(OVERFLOW);//分配内存失败,则退出。
L->length = 0;
L->Listsize = ListInitsize;// 线性表内存为初始化内存数。
return 1;
}
int GetElem(List *L,int i,int *e)//获取线性表第i个元素
{
if(i<1||i>L->length)//若i不在范围内,则退出。
return 0;
*e = L->data[i-1];
return 1;
}
int ListInsert(List *L,int i,int e)//插入e至第i个元素位置,需要将i个元素至最后一个元素向后移动一个位置
{
int *p=malloc(sizeof(int));
int *q=malloc(sizeof(int));
int *newbase; //新分配的动态数组名
if(i<1||i>L->length+1)//若插入位置在最后一个元素的后一个元素之后也要退出
return 0;
if(L->length>=L->Listsize)//判定分配内存空间是否满或溢出了。
{
newbase = realloc(L->data,(L->Listsize+ADD)*sizeof(int));//若满或溢出就重新分配内存 ,将原来的内存空间增加ADD个单位
if(!newbase)
exit(OVERFLOW);//分配内存失败,则异常退出。
L->data = newbase;//新的内存首地址为newbase,将它赋值给data。
L->Listsize += ADD;//性表当前分配的内存为原来的增加ADD。
}
q= &L->data[i-1]; //将q指向第i个元素。
for(p=&L->data[L->length-1];p>=q;p--) //p初始化指向数组最后一个元素,依次递减至指向第i个元素。
*(p+1) = *p;//依次将最后一个元素到第i个元素的值,赋给最后一个元素的后一个元素到 i+1个元素。
//相当于i到最后一个元素整体后移一位。
*q =e; //将e插入第i的位置。
L->length++; //线性表的长度增加1。
return 1;
}
int ListDelete(List *L,int i,int *e)//删除线性表的一个元素,本题用不到。
{
int *p=malloc(sizeof(int));
int *q=malloc(sizeof(int));
if(i<1||i>L->length)
return 0;
p = &L->data[i-1];//指向第i个元素的指针。
*e = *p; //将其值保存在*e中。
q = L->data+L->length-1;//指向最后一个元素的指针。
for(++p;p<=q;p++)
*(p-1) = *p;//将第i+1个元素到最后一个元素向前移动一个位置。
L->length--;
return 1;
}
int ListLength(List L)//获取线性表长度
{
return L.length;
}
void MergeList(List La,List Lb,List *Lc)//将La与Lb中的元素按从小到大的顺序插入到Lc中,从大到小也行,改一下比较符就行。
{
int i=1,j=1,k=0; //i,j,k分别为在表la,lb,lc的位置,即第几个元素,i,j初始化为第一个元素。k初始化为第一个元素之前的位置,后面自增用前缀。
int La_len,Lb_len,ai,bj;
InitList(Lc);
La_len = ListLength(La);
Lb_len = ListLength(Lb);
while(i<=La_len&&j<=Lb_len) //依次从La和Lb中读取较小的元素插入到 Lc中。
{
GetElem(&La,i,&ai);
GetElem(&Lb,j,&bj);
if(ai<=bj)
{
ListInsert(Lc,++k,ai);
i++;
}
else
{
ListInsert(Lc,++k,bj);
j++;
}
}
while(i<=La_len) //当Lb的元素都插入完了,剩下的La的元素依次读取并插入到Lc中。
{
GetElem(&La,i++,&ai);//注意结束上面的循环后,若是Lb的元素插入完,i指向的元素还没有插入到Lc中,因此i自增是后缀。
ListInsert(Lc,++k,ai);
}
while(j<=Lb_len) //这是La插入完的情况,这两个只会执行一个因为有一个是插入完的。
{
GetElem(&Lb,j++,&bj);
ListInsert(Lc,++k,bj);
}
}
int main()
{
int i,e;
List La,Lb,Lc;
InitList(&La);
InitList(&Lb);
printf("创建链表La\n");
for(i=0;i<4;i++)
{
scanf("%d",&e);
ListInsert(&La,i+1,e);
}
printf("创建链表Lb\n");
for(i=0;i<7;i++)
{
scanf("%d",&e);
ListInsert(&Lb,i+1,e);
} //如题创建线性表La,Lb。
printf("数量:%d\n",ListLength(La)+ListLength(Lb));//新的线性表Lc的元素数量,这里是做一个验证,La与Lb的元素数量和与下面打印的数量应该相同。
MergeList(La,Lb,&Lc);
for(i=1;i<=Lc.length;i++)
{
GetElem(&Lc,i,&e);
printf("%d ",e);
}//依次打印新的线性表的元素。
return 0;
}
|
|