所有顺序表的集合操作都在下面,当无序的时候,我默认为保持原集合的元素相对位置不变,写的比较啰嗦,没有硬性要求可以直接简单暴力循环去写
#include<stdio.h>
typedef struct{
int data[100];
int length;
}SqList;
1.求A与B交集C
//a,b有序(默认升序)
void fun_1_1(SqList& a,SqList& b,SqList& c)
{
//双指针算法,i指向a,j指向b,k指向c (属于归并排序里面的思想)
int i = 0,j = 0,k = 0;
while(i < a.length && j < b.length)
if(a.data[i] > b.data[j]) j ++;
else if(a.data[i] < b.data[j]) i ++;
else //若相等则更新c和所有指针
{
c.data[k ++] = a.data[i ++];
j ++;
}
//更新线性表c的长度
c.length = k;
}
//线性表无序
int hash[100010];//因为无序,所以先用哈希存储
void fun_1_2(SqList& a,SqList& b,SqList& c)
{
int k = 0;
for(int i = 0;i < a.length;i ++) hash[a.data[i]] = 1;
for(int i = 0;i < b.length;i ++)//
if(hash[b.data[i]])
c.data[k ++] = b.data[i];
c.length = k;
}
2.求A与C并集C
//线性表有序(默认升序)
void fun_2_1(SqList& a,SqList& b,SqList& c)
{
//两个有序表,归并成一个有序表 (默认升序)
int i = 0,j = 0,k = 0;
while(i < a.length && j < b.length)
if(a.data[i] < b.data[j])
{
c.data[k ++] = a.data[i ++];
c.data[k ++] = b.data[j ++];
}
else if(a.data[i] > b.data[j])
{
c.data[k ++] = b.data[i ++];
c.data[k ++] = a.data[j ++];
}
else//相等的话,只需要放一个
{
c.data[k ++] = a.data[i ++];
j ++:
}
//把剩下的元素放入c
while(i < a.length) c.data[k ++] = a.data[i ++];
while(j < b.length) c.data[k ++] = b.data[j ++];
c.length = k;
}
//线性表无序 (这里的写法是保证归并之后的c,不改变ab中的相对元素位置)
int hash[100010];//因为无序,直接合并,然后用哈希存储去重就可以了
void fun_2_2(SqList& a,SqList& b,SqList& c)
{
//一边合并,一边放入哈希,来防止出现重复
int i = 0,j = 0,k = 0;
while(i < a.length && j < b.length)
//两个值不相等,且前面都没有出现过
if(a.data[i] != b.data[b])
{
if(!hash[a.data[i]])//判断是否重复出现过,防止重复赋值给c
c.data[k ++] = a.data[i];
if(!hash[b.data[j]])//判断是否重复出现过,防止重复赋值给c
c.data[k ++] = b.data[j];
//更新哈希
hash[a.data[i]] = 1;
hash[b.data[i]] = 1;
}
else if(!hash[a.data[i]])//两个值相等的话,判断一个哈希即可
{
c.data[k ++] = a.data[i ++];
j ++;
//更新哈希
hash[a.data[i]] = 1;
hash[b.data[i]] = 1;
}
//把剩下的元素放入c
while(i < a.length)
if(!hash[a.data[i]])
c.data[k ++] = a.data[i ++];
while(j < b.length)
if(!hash[b.data[i]])
c.data[k ++] = b.data[j ++];
//更新线性表c的长度
c.length = k;
}
3.求A与B差集C
//线性表有序(默认升序)
void fun_3_1(SqList& a,SqList& b,SqList& c)
{
//双指针算法,这里要差集,所以谁小先放谁,相等就跳过
int i = 0,j = 0,k = 0;
while(i < a.length && j < b.length)
if(a.data[i] < b.data[j])
c.data[k ++] = a.data[i ++];
else if(a.data[i] > b.data[j])
c.data[k ++] = b.data[j ++];
else//相等跳过
{
i ++;
j ++;
}
//把剩下的元素放入c
while(i < a.length) c.data[k ++] = a.data[i ++];
while(j < b.length) c.data[k ++] = b.data[j ++];
//更新线性表c的长度
c.length = k;
}
//线性表无序(也使用于有序的情况)
int hashA[100010];//因为无序,所以先用哈希存储
int hashB[100010];
void fun_3_2(SqList& a,SqList& b,SqList& c)
{
//把A和B分别放到两个哈希里面
for(int i = 0;i < a.length;i ++) hashA[a.data[i]] = 1;
for(int i = 0;i < a.length;i ++) hashB[a.data[i]] = 1;
int i = 0,j = 0,k = 0;
while(i < a.length && j < b.length)
//因为只要差值,所以只需判断两者都不相同的情况
if(a.data[i] != b.data[b])
{
if(!hashB[a.data[i]])//判断是否重复出现过,防止重复赋值给c
c.data[k ++] = a.data[i];
if(!hashA[b.data[j]])//判断是否重复出现过,防止重复赋值给c
c.data[k ++] = b.data[j];
//更新哈希
hashA[a.data[i]] = 1;
hashB[b.data[i]] = 1;
}
//把剩下的元素放入c
while(i < a.length)
if(!hashB[a.data[i]])
c.data[k ++] = a.data[i ++];
while(j < b.length)
if(!hashA[b.data[i]])
c.data[k ++] = b.data[j ++];
c.length = k;
}
返回目录:
https://www.acwing.com/file_system/file/content/whole/index/content/5976074/
并集会有重复的