您的位置:首页 > 理论基础 > 数据结构算法

数据结构:求集合差集(c/c++)

2017-10-22 17:08 281 查看
用带头结点的单链表表示整数集合,完成以下算法并分析时间复杂度:

(1)设计一个算法求两个集合A和B的差集运算,即C=A-B,要求算法的空间复杂度为O(1),并释放单链表A和B中不需要的结点。

(2)假设集合中的元素按递增排列,设计一个高效算法求两个集合A和B的差集运算,即C=A-B,要求算法的空间复杂度为O(1),并释放单链表A和B中不需要的结点。

#include<stdio.h>
#include<stdlib.h>

typedef struct LNode
{
int data;
struct LNode* next;
} LinkNode;

void DestroyList(LinkNode*L) //销毁线性表函数
{
LinkNode*p=L->next,*q=L;
while(p!=NULL)
{
free(q);
q=p;
p=p->next;
}
free(q);
}

void DispList(LinkNode*L) //输出函数
{
LinkNode*p=L->next;
while(p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}

void CreatList(LinkNode*&L,int a[],int n) //数组数据建立链表函数尾插法
{
LinkNode*p,*q;
L=(LinkNode* )malloc(sizeof(LinkNode));
q=L;
for(int i=0;i<n;i++)
{
p=(LinkNode * )malloc(sizeof(LinkNode));
p->data=a[i];
q->next=p;
q=p;
}
q->next=NULL;
}

void diff1(LinkNode*&A,LinkNode*&B) //第一小题函数
{
LinkNode*a,*b,*a_prior,*b_prior; //a_prior,b_prior分别为遍历循环中a,b节点的前驱节点
a_prior=A;
int T; //辅助变量T
for(a=A->next;a!=NULL;a=a->next) //遍历A中元素
{
b_prior=B;
T=1;
for(b=B->next;b!=NULL;b=b->next) //对A中,每一个元素都遍历一遍B表
{
if(a->data==b->data) //若两表中出现相同元素,则删除A,B中此元素所在节点(删除B中节点为减少以后遍历B表次数)
{
T=0;
a_prior->next=a->next; //跳过a元素将a前后元素链接
free(a);
a=a_prior; //∵这里if后break跳过B循环后A循环会执行a节点前移,既下一刻开始判断被删除节点的下一节点
b_prior->next=b->next; //跳过b元素将b前后元素链接
free(b);
b=b_prior->next;
break;
}
b_prior=b_prior->next;
}
if(T) //若T==0说明原a节点已删除,此刻a节点位置为a_prior位置,下一刻a节点前移,∴a_prior作为a节点的前驱节点此时就不必前移了
a_prior=a_prior->next;
}
}

void diff2(LinkNode*&A,LinkNode*&B) //第二小题函数
{
LinkNode*a=A->next,*b=B->next,*a_prior=A; //a_prior为a节点的前驱节点
while(a!=NULL && b!=NULL)
{
if(a->data > b->data) //若a节点的值大于b节点,则b节点后移
b=b->next;
else if(a->data < b->data) //若a节点的值小于b节点,则a节点后移
{
a_prior=a; //先将a的前驱节点前移,再将a节点前移
a=a->next;
}
else //若两值相等,则删a节点
{ //b不必删除 ∵到后面有销毁函数销毁b,这里删除b并不能像第一题一样减少遍历次数
a_prior->next=a->next; //跳过a元素将a前后元素链接
free(a);
a=a_prior->next;
}
}
}

void main()
{
int A[7]={9,5,6,7,1,8,2},B[4]={8,-1,5,3}; //无序数组,集合运算A-B应该为9,6,7,1,2 (以检测结果)
int a[10]={0,1,2,3,4,5,6,7,8,9},b[5]={2,4,6,8,10}; //有序数组,集合运算a-b应该为0,1,3,5,7,9
LinkNode*LA=NULL,*LB=NULL;
CreatList(LA,A,7); //建立无序链表LA,LB
CreatList(LB,B,4);
diff1(LA,LB); //第一题函数
DestroyList(LB); //根据题目要求释放A和B中不需要的节点,则B链表全删
DispList(LA); //最后(1)题答案即为diff1后的链表A,将答案输出
DestroyList(LA); //第一题已完成,删除原表LA,重置A,B表并开始(2)题
CreatList(LA,a,10); //建立有序表A,B
CreatList(LB,b,5);
diff2(LA,LB);
DestroyList(LB);
DispList(LA);
DestroyList(LA);
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息