带头结点且递增有序的单链表A、B(A、B中元素个数分别为m、n)分别存储了一个集合。设计算法,求A、B的差集 (仅在A中出现不在B中出现),并存在A中,要求保持递增有序性

/*问题:已知带头结点且递增有序的单链表A、B(A、B中元素个数分别为m、n)分别存储了一个集合。设计算法,求A、B的差集
(仅在A中出现不在B中出现),并存在A中,要求保持递增有序性
*/
// 思路:由于AB都是递增有序的,用A中的每一个元素与B中的全部元素作比较,若是相同,则删除该元素节点,这样删除之后剩下的部分也一定是有序的
#include "stdio.h"
#include<stdlib.h>
typedef struct Node{    //结构体
    int data;
    Node *next;
}Node;
void init(Node *&p);
void listCreate(Node *&p,int n);
void Traversal(Node *&p);

void differentSet(Node *&A,Node *&B,int m,int n){   //参数:链表A、b,A元素个数m,B元素个数n
    Node *a = A->next;
    Node *b;
    Node *p = A;   //p作为a的前驱,删除节点的时候用
    int tmp,flag=0;   //tmp存储A的元素,flag标志A有没有发生删除
    while(a!=NULL){
        flag = 0;       
        b = B->next;    //每次a与B中元素比较完b都回到第一个节点
        tmp = a->data;
        while(b!=NULL){
            if(tmp==b->data){  //删除A中值为tmp的节点
                p->next = a->next;
                free(a);
                flag = 1;   //说明发生了删除
                break;      //删除了就可以比较下一个数了,减少比较次数
            }
            b=b->next;  //b后移;
        }
        //根据A是否发生了删除,接下来a与p有两种移动方式:1、发生删除,删除后a为空指针,要让a重新作为p的后继(a=p->next);2、没有发生删除:a、p后移
        //通过判断flag获取接下来的移动方式
        if(flag==1){    //假如发生了删除,那么a就等于p的后继
            a=p->next;
        }else{     //假如没有发生删除,那么a,p都后移;
            p=a;
            a=a->next;
        }
    }
}

int main(){
    Node *A = (Node *)malloc(sizeof(Node));
    Node *B = (Node *)malloc(sizeof(Node));
    init(A);
    init(B);
    int arr1[]={1,2,3,4,7,8,9};  //7
    int arr2[]={4,5,6,7};    //4
    //差集:12389
    for(int i=6;i>=0;i--){
        listCreate(A,arr1[i]); 
    }
    for(int i=3;i>=0;i--){
        listCreate(B,arr2[i]);
    }
    differentSet(A,B,7,4);
    Traversal(A);
    getchar();
    return 0;
}
void init(Node *&p){    //初始化
    p->next = NULL;
}

void listCreate(Node *&p,int n){      //参数:头节点,数据
    Node *q = (Node *)malloc(sizeof(Node));
    //****头插法建立(插入)链表*********(后进先出)
    q->data = n;
    q->next = p->next;
    p->next = q;
    //****************
}



void Traversal(Node *&p){   //遍历
    Node *q = p->next;
    while (q != NULL)
    {
        printf("%d ",q->data);
        q = q->next;
    }
}
posted @ 2020-11-11 09:04  封不烦  阅读(679)  评论(0编辑  收藏  举报