线性表的操作 (2)实现 C = A U B

线性表归并算法
本文介绍了一种线性表归并算法,该算法能够将两个已排序的线性表LA和LB归并成一个新的非递减有序线性表LC。示例中,LA={3,5,8,11}
/*
已知线性表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,8,9,11,11,15,20}
*/
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

#define LIST_INIT_SIZE 10
#define LISTINCREMENT 2

typedef struct SqList
{
	int *elem;
	int length;
	int listsize;
}SqList;

bool InitList(SqList *L); //线性表的初始化
bool ListInsert(SqList *L,int pos,int e); //在线性表第pos位置插入 e
bool ListTraverse(SqList *L); //遍历线性表的元素

bool GetElem(SqList L,int pos,int *e); //用e返回L中第pos个数据的值
int ListLength(SqList L); //求线性表的长度
void MergeList(SqList La,SqList Lb,SqList *Lc);

 
int 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); 
	
	InitList(&Lb); //创建空表 Lb
	for(j = 1; j <= 7; j++)
		ListInsert(&Lb,j,b[j-1]);
	printf("Lb = ");
	ListTraverse(&Lb);
	
	MergeList(La,Lb,&Lc);//将La Lb中的元素插入Lc中
	printf("Lc = "); //输出表Lc的内容
	ListTraverse(&Lc);
	return 0;
}

bool InitList(SqList *L) //线性表的初始化
{
	L->elem = (int *)malloc(LIST_INIT_SIZE*sizeof(int));
	if(L->elem == NULL)
	{
		printf("内存分配失败 程序终止!\n");
		exit(-1);
	}
	L->length = 0;
	L->listsize = LIST_INIT_SIZE;
	return true;
}

bool ListInsert(SqList *L,int pos,int e) //在线性表第pos位置插入 e
{
	int *newbase, *p, *q;
	if(pos < 1 || pos > L->listsize + 1) //pos 值不合法
		return false;
	if(L->length >= L->listsize) //当前存储空间已满 增加分配
	{
		newbase = (int *)realloc(L->elem,(L->listsize + LISTINCREMENT)*sizeof(int));
		if(newbase == NULL)
		{
			printf("内存分配失败 程序终止!\n");
			exit(-1);
		}
		L->elem = newbase; //新基址
		L->listsize += LISTINCREMENT; //增加存储容量
	}
	q = L->elem + pos - 1; // q为插入位值
	for(p = L->elem + L->length - 1; p >= q; --p) //插入位置及之后的元素右移
		*(p+1) = *p;
	*q = e; //插入e
	L->length++; //表长增1
	return true;
}

bool ListTraverse(SqList *L) //遍历线性表的元素
{
	int *p;
	int i;
	p = L->elem;
	for(i = 1; i <= L->length; i++)
		printf("%d ",*p++); // *p++ 先执行*p 再执行p++ 
	printf("\n");
	return true;
}

void MergeList(SqList La,SqList Lb,SqList *Lc)
{
	//已知线性表La和Lb中的数据元素按值非递减排列
	//归并La和Lb得到的新的线性表Lc,Lc的数据元素也按值的 非递减排列
	int i = 1, j = 1, k = 0;
	int La_len, Lb_len;
	int ai, bj;
	InitList(Lc); //创建空表Lc
	La_len = ListLength(La);
	Lb_len = ListLength(Lb);
	while(i <= La_len && j <= Lb_len) //表La和La均为非空
	{
		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) //表La非空且表Lb空
	{
		GetElem(La,i++,&ai);
		ListInsert(Lc,++k,ai);
	}
	while(j <= Lb_len) //表Lb非空且表La空
	{
		GetElem(Lb,j++,&bj);
		ListInsert(Lc,++k,bj);
	}
}

int ListLength(SqList L) //求线性表的长度
{
	return L.length;
}

bool GetElem(SqList L,int pos,int *e) //用e返回L中第pos个数据的值
{
	if(pos < 1 || pos > L.length)
		return false;
	*e = *(L.elem + pos - 1);
	return true;
}
/*
上一个函数的第二中写法 通过址传递
bool GetElem(SqList *L, int pos,int *e) //前面声明函数也与此句保持一致
{
	if(pos < 1 || pos > L->length)
		return false;
	*e = *(L->elem + pos - 1);
	return true;
}
*/

程序执行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值