线性表的删除
描述
已知a、b和c三个递增有序的线性表,现在要求对a做如下操作:删除其中既即在b中出现又在c中出现的元素(注意同一表中的元素有可能重复)。
输入
先在第一行输入3个小于100的正整数m,n,l分别表示顺序表a,b,c的长度,然后在第二行输入m个递增的正整数,第三行输入n个递增的正整数,第四行输入l个递增的正整数,分别为这三个线性表的元素,
输出
按顺序输出删除元素后的线性表a的值,每个元素占一行。
输入样例
3 8 5
23 47 88
2 5 7 9 47 47 88 99
10 20 30 40 47
输出样例
23
88
思路:
和归并类似,同时移动指针,实现删除三个链表中相同的元素时间复杂度为O(n²)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int DataType; /*数据类型*/
typedef int ElemType; /*元素类型*/
//----------------线性列表存储结构----------------
typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
void ListCreate(LinkList L, int n)
//创建含有n个结点的链表
{
int i;
LinkList p, q;
p = L;
for(i = 0 ; i < n; i++)
{
q = (LinkList)malloc(sizeof(LNode)); //生成新结点
scanf("%d", &q->data);
q->next = NULL;
p->next = q; //前后结点链接
p = q;
}
}
void ListMerge(LinkList La, LinkList Lb, LinkList Lc)
{
LinkList pa = La->next, pb = Lb->next;
LinkList pc = Lc;
while(pa && pb)
{
if(pa->data <= pb->data)
{
pc ->next = pa;
pc = pa;
pa = pa->next;
}
else
{
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
pc->next = pa?pa:pb; //插入剩余段
free(La);
free(Lb);
}
void ListTraverse(LinkList L)
{
LinkList p = L;
while(p->next)
{
p = p->next;
printf("%d\n", p->data);
}
}
int main()
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
LNode La, Lb, Lc;
ListCreate(&La, a);
ListCreate(&Lb, b);
ListCreate(&Lc, c);
LinkList pa, pb, pc, pre;
pa = La.next, pb = Lb.next, pc = Lc.next;
pre = &La;
//遍历pa,删除三个表中相同的结点
while(pa)
{
//分别在Lb和Lc中找到第一个大于等于pa的结点
while(pc && pb &&(pb->data<pa->data || pc->data<pa->data))
{
if(pb->data < pa->data)
pb = pb->next;
if(pc->data<pa->data)
pc = pc->next;
}
//Lb或Lc遍历完,停止遍历pa
if(!pb || !pc)
break;
//printf("%d %d %d\n", pa->data, pb->data, pc->data);
if(pb->data == pa->data && pc->data == pa->data)
{
LinkList temp = pa;
//pre所指结点的指针向后移动,pre指针本身不移动
pre->next = pa->next;
pa = pa->next;
free(temp);
}
else
{
pre = pa;
pa = pa->next;
}
}
ListTraverse(&La);
return 0;
}