Renegade12138 2019-05-22 22:07
浏览 233

在devcpp运行不能重复输出并集求求大佬们看看。

第一次在csdn求助!不知道规矩,希望各位大佬能够指点!谢谢大家!
下面是题目和代码,输入完两个集合以后输出两次并集就会出错,还有一个问题是怎么清空链表??
被这两个问题折磨了一星期le
图片说明

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef struct node {
    int data;
    struct node* next;
}node;
int lenth(node* head);
node* build();//创建链表
int IN_SET(node* p, node* head);//判断新元素是否在链表中存在
node* INSERT_SET(node* head);//插入链表
void output0(node* head);
int compare(node* p, node* tail);
node* Plus(node* head1, node* head2);
int IN_SET(node* head1, node* head2);
node* Cross(node* head1, node* head2);
node* Oppo(node* head1, node* head2);

int main()
{
    node* LA = NULL;
    node* LB = NULL;
    node* head_c = NULL;
    node* head_d = NULL;
    node* head_e = NULL;
    int item;

    while (1)
    {
        system("color 9");
        printf("\n0-退出      1-编写集合  2-插入元素   3-输出集合");
        printf("\n4-输出交集  5-输出并集  6-输出对称差 \n");
        printf("请选择要进行的操作:");
        scanf("%d", &item);
        switch (item)
        {
        case(0):
        {
            exit(0);
        }
        case(1):
        {

            if (LA != NULL)
            {

                printf("已经存在链表!!");
                break;
            }

            printf("\n创建集合A:");
            LA = build();
            printf("\n创建完毕");
            printf("\n创建集合B:");
            LB = build();
            printf("\n创建完毕");
            break;
        }
        case(2):
        {
            int t;
            printf("\n输入1将元素插入集合A,输入2将元素插入集合B:");
            scanf("%d", &t);
            switch (t)
            {

            case(1):
            {
                LA = INSERT_SET(LA);
                node* temp1 = LA;

                while (temp1 != NULL)
                {
                    printf("%d   ", temp1->data);
                    temp1 = temp1->next;

                }
                break;
            }
            case(2):
            {
                LB = INSERT_SET(LB);
                break;
            }
            }
            break;
        }
        case(3):
        {
            printf("\n输出A集合:\n");

            output0(LA);
            printf("\n输出B集合:\n");

            output0(LB);
            break;
        }
        case(4):
        {
            printf("\nA与B的交集为:\n");
            head_d = Cross(LA, LB);
            output0(head_d);

            break;
        }
        case(5):
        {
            printf("A与B的并集为:\n");
            head_c = Plus(LA, LB);
            output0(head_c);
            break;
        }
        case(6):
        {
            printf("A与B的对称差为:\n");
            head_e = Oppo(LA, LB);
            output0(head_e);
            break;
        }
        }
    }
}


node* build()
{
    int  size, n = 0;
    node* head = NULL, * newnode = NULL;

    //node* MoveP = head;
    //node* EXMoveP = head;
    printf("\n请输入该集合大小:");
    scanf("%d", &size);
    while (n < size)
    {

        n++;
        newnode = (node*)malloc(sizeof(node));
        newnode->next = NULL;
        //printf("\n请输入你想增加的元素:");
        //scanf("%d", &(newnode->data));

        if (head == NULL)//头指针为空,则替换头指针中的值 
        {
            printf("\n请输入你想增加的元素:");
            scanf("%d", &(newnode->data));
            head = newnode;


            continue;
        }
        head = INSERT_SET(head);//用插入排序进行输入
    }

    //  MoveP = head;//(测试)输出链表,查看链表存储方式
    //  
    //  while (MoveP!=NULL)
    //  {
    //      printf("%d   ", MoveP->data);
    //      MoveP = MoveP->next;
    //  }
    return head;
}



void output0(node * head)//输出函数,已排序的数组从尾部倒着输出 
{
    node* tempnode = head;
    int len = lenth(head);
    if (tempnode == NULL)
    {
        printf("空集");
        return;
    }
    for (int i = 0; i < len; i++)
    {
        node* tail = head;
        for (int j = len; (j - i - 1) > 0; j--)
        {
            tail = tail->next;
        }
        printf("%d  ", tail->data);

    }

}
int compare(node * p, node * tail)//比较两个传入节点的值的大小 ,前者大于后 者,则返回0,否则返回1。 
{
    if (tail == NULL) return 0;
    if ((p->data) > (tail->data)) return 0;
    return 1;
}

node* INSERT_SET(node * head)//插入链表
{



    node* Head = head, * tail = head;
    if (head == NULL)//头指针为空,则说明创建链表不成功,或者未创建链表
    {
        //  printf("②");
        printf("尚未创建集合,请重新输入");
        return head;
    }
    while ((tail->next) != NULL)//将尾指针挪到正确位置
    {
        tail = tail->next;
    }


    while (1)//无限循环,以下每一种条件都会有出口
    {

        node* p = (node*)malloc(sizeof(p));
        p->next = NULL;
        printf("\n请输入插入的元素:");
        scanf("%d", &(p->data));

        if (!IN_SET(head, p))//判断新元素是否已经存在
        {
            printf("\n该元素已在集合中,请重新输入另一个值");
            free(p);
            continue;
        }
        else
        {

            if ((p->data) > (tail->data))//如果新元素大于尾部,直接接上
            {
                tail->next = p;
                tail = p;
                return head;
            }
            else
            {

                node* MoveP = (head->next);//操作指针,用于插入操作的时候连接后半部分链表
                node* EXMoveP = head;//操作指针的前一指针,保证能够比较到每一个值
                if ((p->data) < (head->data))//如果新元素比头部要小,则插在头部之前
                {
                    (p->next) = head;
                    head = p;
                    return head;
                }
                while ((EXMoveP->next) != NULL)
                {
                    if ((p->data) < (MoveP->data))//如果比操作指针要小,则插在操作指针前
                    {
                        (EXMoveP->next) = p;//先替换掉操作指针前一个指针的next入口,这两行不能打乱次序
                        (p->next) = MoveP;
                        return head;
                    }
                    MoveP = (MoveP->next);
                    EXMoveP = (EXMoveP->next);//向后拨动指针
                }
            }
        }



    }
}
node* INSERT_SET0(node* head,node* newnode)//插入链表
{
    node* Head = head, * tail = head;
    if (head == NULL)//头指针为空,则说明创建链表不成功,或者未创建链表
    {
        return head;
    }
    while ((tail->next) != NULL)//将尾指针挪到正确位置
    {
        tail = tail->next;
    }


    while (1)//无限循环,以下每一种条件都会有出口
    {

        node* p = (node*)malloc(sizeof(p));
        p->data = newnode->data;
        p->next = NULL;
        if (!IN_SET(head, p))//判断新元素是否已经存在
        {
            printf("\n该元素已在集合中,请重新输入另一个值");
            free(p);
            return head;
        }
        else
        {
            if ((newnode->data) < (head->data))//尾部插入 
            {
                newnode->next = head;

                head = newnode;
                return head;
            }
            if ((p->data) > (tail->data))//如果新元素大于尾部,直接接上
            {
                tail->next = p;
                tail = p;
                return head;
            }
            else
            {

                node* MoveP = (head->next);//操作指针,用于插入操作的时候连接后半部分链表
                node* EXMoveP = head;//操作指针的前一指针,保证能够比较到每一个值
                while ((EXMoveP->next) != NULL)
                {
                    if ((p->data) < (MoveP->data))//如果比操作指针要小,则插在操作指针前
                    {
                        (EXMoveP->next) = p;//先替换掉操作指针前一个指针的next入口,这两行不能打乱次序
                        (p->next) = MoveP;
                        return head;
                    }
                    MoveP = (MoveP->next);
                    EXMoveP = (EXMoveP->next);//向后拨动指针
                }
            }
        }



    }
}
node* Plus(node * head1, node * head2)//取并集
{
    node* Head1 = head1, * Head2 = head2, * head3 = NULL, * p1 = NULL, * New_tail = NULL;

    while (Head1 != NULL)
    {
        node* p1 = (node*)malloc(sizeof(p1));
        p1->next = NULL;
        (p1->data) = (Head1->data);
        if (head3 == NULL)//令头部和尾部先重合,以创建新链表
        {

            head3 = p1;
            New_tail = p1;

        }
        else
        {

            New_tail->next = p1;
            New_tail = p1;
        }
        Head1 = Head1->next;
    }
    Head1 = head1;
    while (Head2 != NULL)
    {
        if (IN_SET(Head1, Head2))//如果Head1(整个链表)和Head2(一个节点)的值不一样,执行,将不一样的值插入新构建的链表中
        {
            head3=INSERT_SET0(head3, Head2);
        }
        Head2 = Head2->next;
    }
    return head3;
}

int IN_SET(node * head1, node * head2)//在head1为头部的链表中查找是否有与head2节点的值相等的节点,有返回假(0),没有返回真(1)
{
    node* Head1 = head1, * Head2 = head2;
    while (Head1 != NULL)
    {
        if ((Head1->data) == (Head2->data))
            return 0;
        Head1 = Head1->next;
    }
    return 1;
}

node* Cross(node * head1, node * head2)//取交集
{
    node* Head1 = head1, * Head2 = head2, * head3 = NULL, * p1 = NULL, * New_tail = NULL;
    while (Head2 != NULL)
    {
        if (0 == IN_SET(Head1, Head2))//若 Head1链表中有与Head2相同的节点,取出,拼接成为新节点
        {
            node* p1 = (node*)malloc(sizeof(p1));
            p1->next = NULL;
            (p1->data) = (Head2->data);
            if (head3 == NULL)
            {
                head3 = p1;
                New_tail = p1;
            }
            else
            {
                New_tail->next = p1;
                New_tail = p1;
            }
        }
        Head2 = Head2->next;
    }
    return head3;
}


node* Oppo(node * head1, node * head2)//求对称差
{

    node* head3 = NULL, * head4 = NULL, * head5 = NULL, * p1 = NULL, * New_tail = NULL;
    head4 = Plus(head1, head2);

    head3 = Cross(head1, head2);

    while (head4 != NULL)
    {
        if (IN_SET(head3, head4))//如果head3与head4链表中的元素不相同,执行
        {
            node* p1 = (node*)malloc(sizeof(p1));
            p1->next = NULL;
            (p1->data) = (head4->data);//把不相同的元素取出,组成新的链表
            if (head5 == NULL)
            {
                head5 = p1;
                New_tail = p1;
            }
            else
            {
                New_tail->next = p1;
                New_tail = p1;
            }
        }
        head4 = head4->next;
    }
    return head5;
}
int lenth(node * head)//计算链表长度的函数
{
    node* temp = head;
    int i = 0;

    while (temp != NULL)
    {
        i++;
        temp = (temp->next);
    }

    return i;

}

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 运筹学中在线排序的时间在线排序的在线LPT算法
    • ¥30 求一段fortran代码用IVF编译运行的结果
    • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
    • ¥15 lammps拉伸应力应变曲线分析
    • ¥15 C++ 头文件/宏冲突问题解决
    • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
    • ¥50 安卓adb backup备份子用户应用数据失败
    • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
    • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题
    • ¥30 python代码,帮调试,帮帮忙吧