一、问题描述
假设有集合A = {1,2,3,4,5, 6,7, 8 ,9,10 }, 集合B = {6,7,8,9,10,11,12,13,14,15},那么如何去求A U B,和 A n B呢。如果这是一道数学题,相信每个人都可以很快的给出答案,但是当A集合有一千个数据呢,这时候就需要我们花费大量的时间去完成它。如何用代码去实现它呢,首先,得思考用什么方式去存储集合A和集合B
呢,刚开始我想到用数组,但求A U B就必须要把A不存在但B存在的数据放入A中(也可以是B),用数组就很麻烦,其一:在数组定义的时候就必须指明它的大小,也就是说你要开辟多少个字节是固定的,这样的话就很不灵活,数据少了不够用,多了浪费空间。
其二:数组的插入,删除很麻烦,而且很不好用,如果用链表就能完美地解决这个问题。
图解 A U B,A n B
代码实现:
#include <stdio.h>
#include <vld.h>
#include "dseqlist.h"
void Merge(PDSeqList psA,PDSeqList psB)
{
int tmp;
int index;
int lenA;
//for(int i=0;i<psB->length;i++)
for(int i=0;i<GetLength(psB);i++)
{
GetElem(psB,i,&tmp);
index = Search(psA,tmp);
if(index < 0)//A 没有tmp
{
//Insert(psC,0,tmp);//头插
lenA = GetLength(psA);//尾插
Insert(psA,lenA,tmp);
}
}
}
void DisMerge(PDSeqList psA,PDSeqList psB,PDSeqList psC)
{
int tmp;
int index;
int lenA;
//for(int i=0;i<psB->length;i++)
for(int i=0;i<GetLength(psB);i++)
{
GetElem(psB,i,&tmp);
index = Search(psA,tmp);
if(index > 0)//A 没有tmp
{
//Insert(psC,0,tmp);//头插
lenA = GetLength(psC);//尾插
Insert(psC,lenA,tmp);
}
}
}
//todo A=A n B
int main()
{
DSeqList sa;
DSeqList sb;
DSeqList sc;
InitSeqList(&sa);
InitSeqList(&sb);
InitSeqList(&sc);
int i;
for(i=0;i<10;i++)
{
Insert(&sa,i,i);
}
for(i=0;i<10;i++)
{
Insert(&sb,i,i+5);
}
Show(&sa);
Show(&sb);
Merge(&sa,&sb);//A u B
Show(&sa);
//DisMerge(&sa,&sb,&sc);//A n B
//Show(&sc);
//Show(&sb);
return 0;
}
Merge(A UB)结果:
DisMerge(A n B)结果:
链表实现:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "dseqlist.h"
//typedef struct DSeqList
//{
// int *elem;//保存动态创建存放数据内存的地址
// int length;//有效数据个数
// int listsize;//总单元个数(总格子数)
//}DSeqList,*PDSeqList;//12
void InitSeqList(PDSeqList ps)
{
assert(ps != NULL);
if(ps == NULL)
{
return ;
}
ps->elem = (int *)malloc(INITSIZE *sizeof(int));
ps->length = 0;
ps->listsize = INITSIZE;
/*ps->elem = NULL;
ps->length = 0;
ps->listsize = 0;*/
}
static bool IsFull(PDSeqList ps)
{
return ps->length == ps->listsize;
}
//将容量扩大到原来的2倍
static void Inc(PDSeqList ps)
{
ps->elem = (int *)realloc(ps->elem,ps->listsize*2*sizeof(int));
ps->listsize *= 2;
//ps->length;
}
bool Insert(PDSeqList ps,int pos,int val)
{
if(pos<0 || pos>ps->length)
{
return false;
}
if(IsFull(ps))
{
Inc(ps);//扩容
}
for(int i=ps->length-1;i>=pos;i--)//移数据
{
ps->elem[i+1] = ps->elem[i];
}
ps->elem[pos] = val;//插入新数据
ps->length++;
return true;
}
bool DeletePos(PDSeqList ps,int pos)
{
return false;
}
int Search(PDSeqList ps,int key)
{
for(int i=0;i<ps->length;i++)
{
if(ps->elem[i] == key)
{
return i;
}
}
return -1;
}
bool Delete(PDSeqList ps,int key)
{
for(int i=0;i<ps->length;i++)
{
if(ps->elem[i] == key)
{
ps->elem[i] = ps->elem[i+1];
}
ps->length--;
return true;
}
return false;
}
bool IsEmpty(PDSeqList ps);
//获取有效数据个数
int GetLength(PDSeqList ps)
{
return ps->length;
}
//销毁顺序表
void Destroy(PDSeqList ps)
{
free(ps->elem);//1
ps->elem = NULL;//2,提供健壮性
ps->length = 0;//3
ps->listsize = 0;//4
//ps = NULL;//5,没有意义,
}
//清空数据
void Clear(PDSeqList ps)
{
ps->length = 0;
}
void Show(PDSeqList ps)
{
for(int i=0;i<ps->length;i++)
{
printf("%d ",ps->elem[i]);
}
printf("\n");
}
bool GetElem(PDSeqList ps,int pos,int *rtval)
{
if(pos<0 || pos>=ps->length)
{
return false;
}
*rtval = ps->elem[pos];
return true;
}
头文件"dseqlist.h"
#pragma once//防止头文件被多次引用
//不定长顺序表
#define INITSIZE 10
typedef struct DSeqList
{
int *elem;//保存动态创建存放数据内存的地址
int length;//有效数据个数
int listsize;//总单元个数(总格子数)
}DSeqList,*PDSeqList;//12
void InitSeqList(PDSeqList ps);
bool Insert(PDSeqList ps,int pos,int val);
bool DeletePos(PDSeqList ps,int pos);
int Search(PDSeqList ps,int key);
bool Delete(PDSeqList ps,int key);
bool IsEmpty(PDSeqList ps);
//获取有效数据个数
int GetLength(PDSeqList ps);
//销毁顺序表
void Destroy(PDSeqList ps);
//清空数据
void Clear(PDSeqList ps);
void Show(PDSeqList ps);
//rtval输出参数
bool GetElem(PDSeqList ps,int pos,int *rtval);