题目
description:
已知 A,B 和 C 为三个非递减有序的线性表,均以单链表作为存储结构。现要求对 A表作如下操作:删去那些既在 B 表中出现又在 C 表中出现的元素。试对单链表编写实现上述操作的算法,并释放 A 表中的无用结点空间。
input:
第一行输入 3 个正整数 m,n,p(m,n,p<=100),用空格分开,表示三个线性表中的元素个数,其后 3 行依次输入 A,B,C 表中的元素。
output:
输出实现上述操作后的 A 表。
sample_input:
8 5 6
1 2 3 4 5 6 6 7
2 3 5 9 12
2 4 5 6 12 13
sample_output:
1 3 4 6 6 7
思路
同时遍历三个单链表,每次首先比较链表B、C的值,当扫描到链表B、C存在相同的值时,开始扫描链表A,设链表B、C相等的那个值为k,分以下三种情况:
- 链表A中结点值小于k,则继续往后扫描链表A,直到找到链表A中大于或等于k为止;
- 链表A中结点值大于k,则退出扫描链表A的循环,继续往后扫描链表B、C;
- 链表A中结点值等于k,则删除该结点,退出扫描链表A的循环,继续往后扫描链表B、C。
以上操作直到任意链表扫描结束为止。
另外,链表A需要额外多设一个指针,是为了方便进行删除结点操作。
代码
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
typedef struct LNode {
int data;
struct LNode *next;
} LNode;
LNode *createLNode(int n);
LNode *deleteSame(LNode *&A, LNode *&B, LNode *C);
int main() {
int m, n, p;
cin >> m >> n >> p;
LNode *A, *B, *C, *r;
A = createLNode(m);
B = createLNode(n);
C = createLNode(p);
A = deleteSame(A, B, C);
/*输出*/
r = A->next;
while (r) {
cout << r->data << " ";
r = r->next;
}
}
LNode *deleteSame(LNode *&A, LNode *&B, LNode *C) {
LNode *pa, *pb, *pc, *ra;
pa = A->next;
pb = B->next;
pc = C->next;
ra = A;
while (pa && pb && pc) {
if (pb->data == pc->data) {
while (pa) {
if (pa->data < pb->data) {
ra = ra->next;
pa = pa->next;
} else if (pa->data == pb->data) {
ra->next = pa->next;
free(pa);
pa = ra->next;
pb = pb->next;
pc = pc->next;
break;
} else if (pa->data > pb->data) {
pb = pb->next;
pc = pc->next;
break;
}
}
} else if (pb->data < pc->data) {
pb = pb->next;
} else
pc = pc->next;
}
return A;
}
LNode *createLNode(int n) {
LNode *L, *s, *r;
L = (LNode *)malloc(sizeof(LNode));
r = L;
r->next = NULL;
for (int i = 0; i < n; i++) {
s = (LNode *)malloc(sizeof(LNode));
cin>>s->data;
r->next = s;
r = s;
}
r->next = NULL;
return L;
}