• 链表交集、合并、排序


    第四周

    要求:

    1、将两个有序的递增链表合并为一个递增的有序链表。要求结果链表仍使用原来两个链表的储存空间,不另外占用其他的储存空间。表中不允许有重复数据。

    2、已知两个链表A和B分别表示两个集合,其元素递增排列。设计一个算法用于求出A与B的交集,并存放在A链表中。

    思路:首先就是创建链表。一般有前插法和后插法;二 要求递增的话可以用一个排序算法(简单看了一下冒泡排序)。三 链表显示和销毁函数。

     四 重点就是合并和交集函数。注意就是对链表操作要释放多余的存储空间,比如:头结点,重复元素结点等

    先定义结构

    typedef struct LNode//定义结构
    {
        int data;
        struct LNode *next;
    }LNode, *Head;

    一、创建链表(后插法)

    Head Create(void)//创建链表
    {
        LNode *head, *r, *p;
        head = new LNode;
        if (head == NULL)
            cout << "头结点创建失败!
    ";
        p = head;
        int x, cycle = 1;
        while (cycle) {
            cout << "输入一个整数.
    ";
            cin >> x;
            if (x != 0) {
                r = new LNode;
                r->data = x;
                p->next = r;
                p = r;
            }
            else {
                cycle = 0;
            }
        }
        p->next = NULL;
        cout << "链表创建成功!
    ";
        return head;
    }

    二、排序(递增)

    Head Order(Head head)//链表节点排序
    {
        LNode *p = head->next, *q = head->next;
        if (!p)
            return head;
        int i = 0, temp = 0, flag = 1;
        while (q) {
            q = q->next;
            ++i;//数据节点个数i
        }
        while (flag && i >= 0) {//冒泡排序
            flag = 0;
            while (p->next != NULL) {
                if (p->data > p->next->data) {
                    temp = p->data;
                    p->data = p->next->data;
                    p->next->data = temp;
                    flag = 1;//标志置为1表示本轮有交换
                }
                p = p->next;
            }
            --i;
            p = head->next;//重新指向首元结点为下轮准备
        }
        return head;
    }

    三、链表显示

    Status print(Head head)
    {
        int i = 0;
        LNode *p = head;
        while (!p)
            return OK;
        while (p->next != NULL)
        {
            p = p->next;
            cout << p->data;
            cout << "   ";
            ++i;
        }
        cout << "   共有"<<i<<"个元素
    ";
        return OK;
    }

    四、销毁链表

    Status DestroyList(Head head)
    {
        LNode *p;
        while (head->next != NULL)
        {
            p = head;
            head = head->next;
            delete p;
        }
        delete head;
        return OK;
    }

    五、链表交集

    交集AB链表放入A链表中,释放B链表;head1为A链表,head2为B链表。

    Head Intersection(Head head1, Head head2)//交集放入A链表
    {
        LNode *head = NULL, *p1 = NULL, *p2 = NULL, *p = NULL;
        head = head1;
        //交集为空
        while (head1->next==NULL || head2->next==NULL) {
            while (head2->next != NULL)//A为空链表 直接删除B链表
            {
                p = head2;
                head2 = head2->next;
                delete p;
            }
                delete head2;
                return head1;
                break;
        }
        LNode *move = head, *temp = NULL;
        p1 = head1->next;
        p2 = head2->next;
        delete head2;
        //AB均不为空
        while (p1&&p2->next != NULL){
            if (p1->data < p2->data)
                p1 = p1->next;
            else if (p1->data > p2->data)
                p2 = p2->next;
            else if (p1->data == p2->data)
            {
                move->next = p1;
                move = p1;
                p1 = p1->next;
            }
        }
        if (p2->next == NULL) {//判断B链表最后一个结点
            if (p1->data == p2->data)
            {
                move->next = p1;
                move = p1;
                p1 = p1->next;
            }
        }
            move->next = NULL;//尾部指针为NULL
        return head;
    }

    六、链表合并

     这里AB合并后放入B链表中。

    Head Combine(Head head1, Head head2)//合并后放入B链表
    {
        LNode *head=head2, *p1=NULL, *p2=NULL;
        if (head1->next==NULL) {//A为空链表或者AB都为空
            delete head1;
            return head2;
        }
        else if (head2->next == NULL) {//B为空链表
            head2->next = head1->next;//A链表赋给B链表
            delete head1;
            return head2;
        }
        p1 = head1->next;
        p2 = head2->next;
        delete head1;
        LNode *move = head, *temp = NULL;
        //按递增顺序依次链接
        while (p1&&p2) {
            if (p1->data < p2->data) {
                move->next = p1;
                move = p1;
                p1 = p1->next;
            }
            else if (p1->data > p2->data) {
                move->next = p2;
                move = p2;
                p2 = p2->next;
            }
            else if(p1->data == p2->data) {//相同数据只保存一个,p1p2向后移一位
                temp = p2;
                move->next = p1;
                move = p1;
                p1 = p1->next;
                p2 = p2->next;
                delete temp;//删除p2相同结点
            }
    
        }
        if (p1)//p2为NULL,直接连接p1后面的结点
            move->next = p1;
        if (p2)//p1为NULL,直接连接p2后面的结点
            move->next = p2;
        return head;
    }

    测试

    int main()
    {
        cout << "创建一个链表A. 输入0结束
    ";
        Head head1 = Create();
        cout << "创建一个链表B. 输入0结束
    ";
        Head head2 = Create();
        char ch;
        while (1) {
            cout << "---------------------------------------------------------------------------
    ";
            cout << "+请选择要进行的操作:<a>显示A   <b>显示B   <c>交集AB   <d>合并AB   <x>退出+
    ";
            cout << "---------------------------------------------------------------------------
    ";
            ch = _getwch();
            if (ch == 'a') {
                cout << "A链表:";
                print(Order(head1));
            }
            else if (ch == 'b') {
                cout << "B链表:";
                print(Order(head2));
            }
            else if (ch == 'c') {
                cout << "AB交集为:";
                print(Order(Intersection(head1, head2)));
                cout << "输入任意字符结束
    ";
                ch = _getwch();
                DestroyList(head1);
                break;
            }
            if (ch == 'd') {
                cout << "AB合并为:";
                print(Order(Combine(head1, head2)));
                cout << "输入任意字符结束
    ";
                ch = _getwch();
                DestroyList(head2);
                break;
            }
            else if (ch == 'x') {
                    break;
            }
        }
    
    }

    运行结果:

    交集:

    合并:

  • 相关阅读:
    Spring Boot 启动加载数据 CommandLineRunner(一般用于项目启动时,用户信息的缓存)
    缓存穿透、缓存并发、缓存失效之思路变迁
    知识点的梳理
    windows下查找java应用占用CPU过高问题
    Java开发中的Memcache原理及实现
    malloc函数详解 C语言逻辑运算符
    PCH 警告:标头停止点不能位于宏或#if块中
    绪论-第一章-《数据结构题集》
    线性表的顺序存储结构--用数组实现
    第二章 《C++ Primer Plus》
  • 原文地址:https://www.cnblogs.com/cjwen/p/10583722.html
Copyright © 2020-2023  润新知