Bootstrap

05 单链表的删除(严 2.29)

题目

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,分以下三种情况:

  1. 链表A中结点值小于k,则继续往后扫描链表A,直到找到链表A中大于或等于k为止;
  2. 链表A中结点值大于k,则退出扫描链表A的循环,继续往后扫描链表B、C;
  3. 链表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;
}
;