本次实验包含求单链表的交集和差集,并作用在一个单链表的上面,为了实现两个函数的测试,需要用到几个函数。第一:1、初始化 2、尾插法 3、删除节点 4、遍历节点。这四个函数写好后,我们就可以愉快的给1交集和差集做测试了。我们先谈论交集如何做。
交集
原题再现:
- 1、已知两个链表A和B分别表示两个集合,其元素递增排列。 请设计一个算法,用千求出A与B的交集,并存放在A链表中。
拿到题目时,先看他输入输出与功能,功能才限制他的输出,输入就是两个单链表,A是要操作的,所以需要加上&。核心关键词:递增、交集.
假设A = {1,2,3,4,8},B={2,4,7,8,9}
那么A∩B= {2,4,8}
算法思路
- 两个操作指针p和q指向两个链表的数据域
- while循环判断p->data 和q->data 如果相等不操作直接下一条,如果大于q跳向下一条地址 ,如果小于,删除节点,最后就是想要的结果了。
根据思路,算法就很简单的转化为代码。
void Inter(LinkList &A,LinkList B){
LinkList p = A->next;
LinkList q = B->next;
while(p && q){
if(p->data == q->data){
p =p->next;
q = q->next;
}else if(p->data>q->data){
q = q->next;
}else{
p = ListDelete(A,p->data);
p = p->next;
}
}
}
差集
题目再现
- 2、巳知两个链表 A和 B分别表示两个集合,其元素递增排列。请设计算法
- 求出两个集合 A和B 的差集(即仅由在A中出现而不在B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。
假设 A = {1,2,3,4,8} B={2,4,7,8,9}
A-B = {1,3} 2个
算法步骤,上题同理
- 两个操作指针p和q指向两个链表的数据域
- while循环判断p->data 和q->data 如果相等删除节点,如果大于q跳向下一条地址 ,如果小于,计数器+1。
int Differ(LinkList &A,LinkList B){
int cnt=0;
LinkList p = A->next;
LinkList q = B->next;
while(p && q){
if(p->data == q->data){
p = ListDelete(A,p->data);
p = p->next;
q = q->next;
}else if(p->data>q->data){
q = q->next;
}else {
p = p->next;
cnt ++;
}
}
return cnt;
}
测试效果
完整源码
#include<iostream>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define MAXSIZE 10
using namespace std;
typedef int Status;
typedef int ElementType;
typedef struct LNode{
ElementType data;
struct LNode* next;
}LNode,*LinkList;
Status InitList(LinkList &L){
L = new LNode;
L->next = NULL;
return OK;
}
void CreateList_H(LinkList &L,int A[],int n){
InitList(L);
LinkList r = L;
for(int i =0;i<n;i++){
LinkList p = new LNode;
p->data = A[i];
p->next = NULL;
r->next = p;
r = p;
}
}
void Print(LinkList L){
LinkList p = L->next;
while(p){
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
LinkList ListDelete(LinkList &L,int x){
LinkList p = L,pre;
while(p->next != NULL && p->data !=x){
pre = p;
p=p->next;
}
pre->next = p->next;
delete p;
return pre;
}
/*
* * 1、已知两个链表A和B分别表示两个集合,其元素递增排列。
* 请设计一个算法,用千求出A与B的交集,并存放在A链表中。
* A = {1,2,3,4,8},B={2,4,7,8,9}
* A∩B= {2,4,8}
* */
void Inter(LinkList &A,LinkList B){
LinkList p = A->next;
LinkList q = B->next;
while(p && q){
if(p->data == q->data){
p =p->next;
q = q->next;
}else if(p->data>q->data){
q = q->next;
}else{
p = ListDelete(A,p->data);
p = p->next;
}
}
}
/*
* 2、巳知两个链表 A和 B分别表示两个集合,其元素递增排列。请设计算法
* 求出两个集合 A和B 的差集(即仅由在A中出现而不在B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。
* A = {1,2,3,4,8} B={2,4,7,8,9}
* A -B={1,3} 2个
* */
int Differ(LinkList &A,LinkList B){
int cnt=0;
LinkList p = A->next;
LinkList q = B->next;
while(p && q){
if(p->data == q->data){
p = ListDelete(A,p->data);
p = p->next;
q = q->next;
}else if(p->data>q->data){
q = q->next;
}else {
p = p->next;
cnt ++;
}
}
return cnt;
}
int main(){
LinkList A,B;
int a[5]={
1,2,3,4,8};
int b[5] ={
2,4,7,8,9};
CreateList_H(A,a,5);
CreateList_H(B,b,5);
cout << "A list:" << endl;
Print(A);
cout << "B list:" << endl;
Print(B);
cout << "A and B intersect: " << endl;
Inter(A,B);
Print(A);
cout << "A and B Difference:" << endl;
CreateList_H(A,a,5);
int cnt = Differ(A,B);
Print(A);
cout << "cnt:" << endl;
cout << cnt << endl;
return 0;
}