【练习】归并和冒泡两种方法c++将两个无序链表合并为一个升序的有序链表_march of Time的博客-程序员秘密

技术标签: C++/c  链表  数据结构  

定义:

struct node {
    
    int data;
    node* next;

};

新建有头指针的链表:

struct node *head;
head = NULL;//头指针初始为空
struct node *p;
//动态申请一个空间,用来存放一个结点,并用临时指针p指向这个结点
p=(struct node *)malloc(sizeof(struct node));
scanf("%d",&a);
p->data=a;//将数据存储到当前结点的data域中
p->next=NULL;//设置当前结点的后继指针指向空,也就是当前结点的下一个结点为空

完整版本:

#include <stdio.h>
#include <stdlib.h>
//这里创建一个结构体用来表示链表的结点类型
struct node
{
    
int data;
struct node *next;
};
int main()
{
    
struct node *head,*p,*q,*t;
int i,n,a;
scanf("%d",&n);
head = NULL;//头指针初始为空
for(i=1;i<=n;i++)//循环读入n个数
{
    
scanf("%d",&a);
//动态申请一个空间,用来存放一个结点,并用临时指针p指向这个结点
p=(struct node *)malloc(sizeof(struct node));
p->data=a;//将数据存储到当前结点的data域中
p->next=NULL;//设置当前结点的后继指针指向空,也就是当前结点的下一个结点为空
if(head==NULL)
head=p;//如果这是第一个创建的结点,则将头指针指向这个结点
else
q->next=p;//如果不是第一个创建的结点,则将上一个结点的后继指针指向当前结点
q=p;//指针q也指向当前结点
}
//输出链表中的所有数
t=head;
while(t!=NULL)
{
    
printf("%d ",t->data);
t=t->next;//继续下一个结点
}
getchar();getchar();
return 0;
}

合并采用先分别升序后再进行合并两个有序链表,分别升序采用双指针和递归调用。先看用归并排序:

用归并排序:

node* merge(node* p,node*p2) {
    //这里是合并的排序
    node* src = new node;
 src->next = nullptr;
    //src->data = 0;
    node* now = src;
    node* a1 = p;
    node* a2 = p2;
    while (a1 != NULL && a2 != NULL) {
    
        if (a1->data >= a2->data) {
    
            node* tem = a2->next;
            src->next = a2;
            a2 = tem;
        }
        else {
    
            node* tem = a1->next;
            src->next = a1;
            a1 = tem;
        }
        src = src->next;//合并两个有序链表 src->next=nullptr
    }
    if (a1 != NULL) src->next = a1;
    if (a2 != NULL)src->next = a2;
    return now->next;


}
node* merge_sort(node* p) {
    //这是将一个链表进行升序
    if (p == nullptr || p->next == nullptr) return p;
    node* fast = p;
    node* slow = new node;
    slow->data = 0;
    slow->next = p;

    while (fast != NULL && fast->next != NULL) {
    
        fast = fast->next->next;
        slow = slow->next;
    }
    node* rhead = slow->next;
    slow->next = NULL;
    node* lh = merge_sort(p);

    node* rh = merge_sort(rhead);
  
    node* after = merge(lh, rhead);
    return after;
}
int main()
{
    
    srand(0);
    node* m = new node;
   
    m->data = rand()%5;
    //cout << m->data;
    node* n = new node;
    n->data = rand()%7;
    m->next = n;
    
    node* nn = new node;
 
    nn->data = rand()%8;
    n->next = nn;
    nn->next = nullptr;
    node* copy_m = m;
    cout << "第一个链表:";
    while (copy_m) {
    
        cout << copy_m->data;
        copy_m = copy_m->next;
    }
    cout << endl;
    node* m2 = new node;
    m2->data =rand()%18;
    
    node* n2 = new node; 
    n2->data = rand() % 13;
    m2->next = n2;

    node* nn2 = new node;

    nn2->data = rand()%15;
    n2->next = nn2;
    nn2->next = nullptr;
    node* copy_n = m2;
    cout << "第二个链表:";
    while (copy_n) {
    
        cout << copy_n->data;
        copy_n = copy_n->next;
    }
    cout << endl;
   node*one = merge_sort(m);

   node*two= merge_sort(m2);
    node* new_m = merge(one,two);
    node* nice = new_m;
    cout << endl;
    cout << "合并两个有序链表后的结果:";
    while (nice) {
    
       
        cout << nice->data << "->";
        nice = nice->next;
    }
}

结果:
在这里插入图片描述

用冒泡排序:

node* merge_sort(node* p) {
    //这是将一个链表进行升序
    if (p == nullptr || p->next == nullptr) return p;
    node* mana = p;
    
    node* pp = mana;
  
    for (int i = 0; i < len(p) - 1; i++) {
    
        mana = p;
        for (int j = 0; j < len(p) - i - 1; j++) {
    
            node* t1 = mana;
            node* t2 = mana->next;
            if (t1->data > t2->data) {
    
                int tem = t1->data;
                t1->data = t2->data;
                t2->data = tem;
            }
            mana = mana->next;
        }
    }
    return pp;
}
int main()
{
    
    srand(0);
    node* m = new node;
   
    m->data = rand()%12;
    //cout << m->data;
    node* n = new node;
    n->data = rand()%17;
    m->next = n;
    
    node* nn = new node;
 
    nn->data = rand()%18;
    n->next = nn;
   

    node* nnn = new node;

    nnn->data = rand() % 23;
    nnn->next = NULL;
    nn->next = nnn;
    node* copy_m = m;
    cout << "第一个链表:";
    while (copy_m) {
    
        cout << copy_m->data<<"-";
        copy_m = copy_m->next;
    }
    cout << endl;
    node* m2 = new node;
    m2->data =rand()%18;
    
    node* n2 = new node; 
    n2->data = rand() % 13;
    m2->next = n2;

    node* nn2 = new node;

    nn2->data = rand()%15;
    n2->next = nn2;
    nn2->next = nullptr;
    node* copy_n = m2;
    cout << "第二个链表:";
    while (copy_n) {
    
        cout << copy_n->data << "-";
        copy_n = copy_n->next;
    }
    cout << endl;
   node*one = merge_sort(m);

   node*two= merge_sort(m2);
    node* new_m = merge(one,two);
    node* nice = new_m;
    cout << endl;
    cout << "合并两个有序链表后的结果:";
    while (nice) {
    
       
        cout << nice->data << "->";
        nice = nice->next;
    }
}

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41358574/article/details/115686090

智能推荐

ZigBee协议栈(二)--OSAL控制LED灯_逍遥l天的博客-程序员秘密

说在前面:上一篇介绍了无线LED闪烁实现的OSAL部分,本篇介绍如何实现无线数据收发及数据处理: 上一篇是用SI跟着流程查看源码,我个人认为以架构的思维去了解代码能让人更清晰  ::ZMain.c程序入口文件这里chipcon_cstartup.s51是汇编的启动文件,ZMain.c相当于main文件,里面有main函数: 1 int m

Go 闭包与匿名函数这一篇就够了_go 闭包 是不是就是匿名函数?_济源IT小伙一枚的博客-程序员秘密

最近在看go语言中的defer,里面涉及到了闭包,之前只是对闭包有了解,但是并没有深入的研究过,这次就深入研究一下吧。本文主要从如下几个点来展开描述,希望对你有所帮助~1、匿名函数的定义与实现2、闭包的定义 [穿插讲引用环境的定义]3、闭包的实现4、关于闭包你需要掌握的几个点:(1)闭包与逃逸分析(2)闭包与外部函数的生命周期(3)通过for循环的案例分析闭包对引用环境中变量的调用问...

linux查看某个端口的流量_linux流量查看工具汇总_weixin_39895977的博客-程序员秘密

时时了解服务器的流量占用情况,是运维人员要掌握的一个入门技能。不过查看流量的情况的手段很多,工具也很多。如ifconfig脚本实现法、cacti、pnp4nagios、mrtg绘图查看以及iptraf、iftop、nload、sar时时查看等 。本文我们就总结下最后提到的四个时时查看的工具。一、iptraf在最的常用的linux发行版centos、redhat源中,可以直接通过yum进行安装。当然...

Android:获得屏幕物理尺寸、密度及分辨率_android physical density_sunguodong1001的博客-程序员秘密

一、分辨率需要注意的原来经常使用的getHeight()与getWidth()已经不推荐使用了,建议使用getSize()来替代。此方法原型如下:[java] view plain copy public void getSize(Point outSize) {      synchronized (this) {         

超分之VRT_vrt模型_Ton10的博客-程序员秘密

2022年推出的基于Vision-Transformer的并行视频超分模型——VRT

ECharts折线图设置预警基线和分段颜色_echarts预警线_哎呦喂O_o嗨的博客-程序员秘密

效果图:代码如下:option = { title: { text: '近十天PM2.5值变化', subtext: '纯属虚构' }, tooltip: { trigger: 'axis', formatter:function(params) {      var relVal = params[0].name; for (var i = 0, l = param

随便推点

如何完整迁移git仓库到另一个远程地址_复制项目到另一个远程地址_鱼龙变1967的博客-程序员秘密

项目中遇到git仓库迁移,很常见。如何把一个项目中所有的分支,tag等迁移到另一个仓库地址,下面两种方式都**亲测可用**。1. 通过命令行进行克隆、推送需要执行一个特别的克隆命令,然后镜像push到新的仓库地址。具体步骤如下:1.打开命令行工具2.以bare的方式克隆老的仓库 git clone --bare https://xx/xx/old-repository.git 3....

网吧管用之招(三)- 系统安装与调试备忘录(转)_cuankuangzhong6373的博客-程序员秘密

网吧管用之招(三)- 系统安装与调试备忘录网吧用机系统安装与调试当然是以网吧用机的实际所需为基准,针对网吧所用软硬件范围而定。我认为主要是所选系统内容精简、功能模块是最新优化且经得起各类应用软件的折腾,同时系统资源泄漏最少。没用...

C++面试题_微积粉的博客-程序员秘密

1、大端与小端的概念?各自的优势是什么?【答】大端与小端是用来描述多字节数据在内存中的存放顺序,即字节序。大端(Big Endian)是指低地址端存放高位字节,小端(Little Endian)是指低地址端存放低位字节。Big Endian:符号位的判定固定为第一个字节,容易判断正负。 Little Endian:长度为1,2,4字节的数,排列方式都是一样的,数据类型转换非常方便。2、...

pytorch系统学习_周月亮的博客-程序员秘密

若想进行in-place操作,就比方说y加上x,y的值就改变了,就可以用y.add_(x)这样y就直接被改变了。Torch里面所有带““的操作,都是in-place的。例如x.copy(y)argmax函数:torch.argmax(input, dim=None, keepdim=False)返回指定维度最大值的序号,也就是变成dim这个维度的最大值的index。构建深度学习模型的基本流程...

Java语言基础------常量变量及运算符_学习造轮子的博客-程序员秘密

常量的定义与分类常量:在程序执行过程中值不发生改变的量,常量又可分为字面值常量和自定义常量。 字面值常量又分为:字符串常量,整数常量,小数常量,字符常量,布尔常量,空常量。 Java对整数常量提供了四种表现形式:二进制、八进制、十进制、十六进制。 Java中整数默认是十进制,八进制使用0开头,十六进制以0X开头。原码反码补码原码:就是二进制定点表示法,既最高位为符号位,“0”表示正...

mplab下和中断相关的编译错误_mplab编译报错_ack26的博客-程序员秘密

error: variable has incomplete type 'void'error: expected ';' after top level declarator。我在mplab x 5的帮助中发现了解决方法,有如下图片我依照帮助进行修改后,编译成功。后面还有很多坑,就说道这里吧。不得不说pic的开发体验真的一言难尽!!!糟糕的体验,糟糕的生态环境。糟...

推荐文章

热门文章

相关标签