一.概述

  在了解排序算法的同时,想到用多线程排序减少排序的时间,所以写了一个简单的示例,加深印象。下面是具体代码

二.内容

  环境:vs2017,.net  core 2.2 控制台程序。

  运行时使用release会减少运行时间,因为debug时调试模式,vs会进行检测。

  详细代码:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading; namespace coreCW
{
  class Program
  {
    static void Main(string[] args)
    {     Random rd = new Random();
    int[] arr = new int[];     //随机生成数组
    for (long i = ; i < arr.Length; i++)
    {
      arr[i] = rd.Next(, );
    }     //线程数组
    List<Thread> tList = new List<Thread>();     //计时器
    Stopwatch sw = new Stopwatch();
    sw.Reset();
    sw.Start();     int tmun =; //线程数
    //循环开启线程进行分段排序,并加入线程列表
    for (int i = ; i < tmun; i++)
    {
      int size = arr.Length / tmun;
      Thread t = new Thread((object obj) =>
      {
        int index = Convert.ToInt32(obj);
        Merge_Sort(arr, size * index, size * (index + ) - );
      });
      tList.Add(t);
      t.Start(i);
    }     //join主线程等待所有线程完成后,继续向下运行
    for (int i = ; i < tList.Count; i++)
    {
      Thread t = tList[i];
      t.Join();
    }     //合并数组
    for (int i = ; i < tmun; i++)
    {
      int size = arr.Length / tmun;
      Merge(arr, , size * i - , size* (i + ) - );
    }     sw.Stop();
    Console.WriteLine("排序总共花费{0}ms.", sw.Elapsed.TotalMilliseconds);
    Console.WriteLine("Thread Finished!");
    Console.WriteLine("===================");
    //foreach (var item in arr)
    //{
    // Console.WriteLine(item);
    //}
  }   //归并排序
  public static void Merge_Sort(int[] arr, int left, int right)
  {     if (left < right)
    {
      int middle = (left + right) / ;
      Merge_Sort(arr, left, middle);
      Merge_Sort(arr, middle + , right);
      Merge(arr, left, middle, right);
    }
  } /// <summary>
/// 归并排序合并
/// 将有序的两个序列分别加两个数组,从数组顶端取两个进行比较,取其小的放入原数组,直至两数组的元素取完
/// </summary>
/// <param name="arr"></param>
/// <param name="left"></param>
/// <param name="middle"></param>
/// <param name="right"></param>
  public static void Merge(int[] arr, int left, int middle, int right)
  {
    int i = middle - left + ;
    int j = right - middle;     //新建两个数组将两部分元素赋予其中
    int[] arrLeft = new int[i];
    int[] arrRight = new int[j];
    for (int k = ; k < i; k++)
    {
      arrLeft[k] = arr[left + k];
    }     for (int k = ; k < j; k++)
    {
      arrRight[k] = arr[middle + k + ];
    }     //分别从两个数组中取值
    int m = , n = ;
    for (int l = ; l < right - left + ; l++)
    {
      if (m >= arrRight.Length)
      {
        arr[left + l] = arrLeft[n];
        n++;
      }
      else if (n >= arrLeft.Length)
      {
        arr[left + l] = arrRight[m];
        m++;
      }
      else if ((arrLeft[n] > arrRight[m]))
      {
        arr[left + l] = arrLeft[n];
        n++;
      }
      else
      {
        arr[left + l] = arrRight[m];
        m++;
      }
    }
  }
 }
}

三.总结

  多线程排序在一定程度上会减少代码运行时间,但并不是开启的线程越多速度就越快,当线程开启到一定数量就会达到瓶颈(线程数需要根据机器性能和具体测试结果来决定以及时间复杂度计算公式得出),或者反而降低速度。单线程的归并排序是一个线程递归所有子数组排序。多线程是将数组分为若干部分,将其交给各个线程并行排序,待所有线程工作完毕后对所有数组进行合并,所以多线程排序加快了子数组的排序过程,虽然最后多线程需要合并,但是在使用单线程的时候也会经历类似的合并过程,所以多线程排序并未增加额外的合并次数,(计算时间复杂度可以记录代码每一步的时间复杂度相加可以得出一个问题规模与时间复杂度的公式),另外可以对排序算法进行更换或优化,比如归并排序在数量比较小的情况速度会比选择排序要慢一点,所以可以优化归并排序,使其在比较小的数量级上使用选择排序或插入排序。

  多线成排序和多线程搜索在实际工作中也是比较常用的.

.net多线程归并排序的更多相关文章

  1. 多线程归并排序的实现 java

    多线程是非常适合归并排序的,因为归并排序是分治法,所以分割后可以独立运行,最后将结果归并起来就行了.如何写一个多线程程序呢?今天无聊,总结一下啊. 首先写个普通的归并排序,以后的多线程就调用这个排序. ...

  2. 归并排序 求逆序数 链表的归并排序 多线程归并排序 java

    import java.util.Scanner; public class Main { private static int count=0; public static void mergeso ...

  3. 多线程归并排序(摘自githhub)

    package com.rationalcoding.sort; import java.util.ArrayList; import java.util.Arrays; import java.ut ...

  4. pthread 多线程基础

    本文主要介绍如何通过 pthread 库进行多线程编程,并通过以下例子进行说明. 基于莱布尼兹级数计算 \(\pi\) . 多线程归并排序 参考文章: [1] https://computing.ll ...

  5. 秋招落幕,对自己的总结by2018-10-20

    在今天阿里沟通offer完毕,正式三方也确定了,一切如梦,想想1月的自己还担心未来的自己会花落谁家,到10月的今天,一切尘埃落地.一直不怎么喜欢总结自己的历程,今天无聊的我也总结一波吧. 准确的说没有 ...

  6. java归并排序,单线程vs多线程

    一.什么是归并排序 归并排序又称合并排序,它是成功应用分治技术的一个完美例子.对于一个需要排序的数组A[0..n-1],归并排序把它一分为二:A[0..n/2-1]和A[n/2..n-1],并对每个子 ...

  7. 关系型数据库工作原理-归并排序(翻译自Coding-Geek文章)

    本文翻译自Coding-Geek文章:< How does a relational database work>. 原文链接:http://coding-geek.com/how-dat ...

  8. Linux多线程实践(10) --使用 C++11 编写 Linux 多线程程序

    在这个多核时代,如何充分利用每个 CPU 内核是一个绕不开的话题,从需要为成千上万的用户同时提供服务的服务端应用程序,到需要同时打开十几个页面,每个页面都有几十上百个链接的 web 浏览器应用程序,从 ...

  9. 使用C++编写linux多线程程序

    前言 在这个多核时代,如何充分利用每个 CPU 内核是一个绕不开的话题,从需要为成千上万的用户同时提供服务的服务端应用程序,到需要同时打开十几个页面,每个页面都有几十上百个链接的 web 浏览器应用程 ...

随机推荐

  1. cxk不会二进制 (贪心)

    cxk不会二进制 Description 最近cxk迷上了二进制,他很菜,有道简单的题不会做,挂在这里求大佬做一下: 以二进制形式给出两个数字:x,y.令s = x + y * 2 ^ k.输出能使 ...

  2. STL(六)——map、multimap

    STL--map.multimap 文章目录 STL--map.multimap 关联容器与map的介绍 map与set的异同 map与multimap的异同 map类对象的构造 map添加元素 ma ...

  3. C++判断输入是否为double

    C++判断输入是否为double 之前写过了Python如何判断输入字符串是否为数字,但是Python是弱类型语言,相比之下C++这种强类型语言判定难度更大. Python判断输入字符串是否为数字的方 ...

  4. PowerShell入门简介

    文章更新于:2020-03-03 一.PowerShell简介 说实话,我总感觉 PowerShell 是 cmd 的加强版,但是看官方介绍,功能甚是强大,用处有待我们发掘. 二.PowerShell ...

  5. go 结构开发规范

    机构规范: // 当前程序的包名 package main //导入其他的包 import "fmt" //常量的定义 const PI=3.14 //全局变量的声明和赋值 var ...

  6. Typora+PicGo+GitHub实现md自带图床效果

    1 GitHub创建作为图床的仓库 1.1 在GitHub中创建一个仓库 注意仓库要是public的,不然上传的图片还是无法使用的.如果不知道怎么创建仓库,可以百度一下. 1.2 在GitHub生成一 ...

  7. 实例讲解Springboot整合MongoDB进行CRUD操作的两种方式

    1 简介 Springboot是最简单的使用Spring的方式,而MongoDB是最流行的NoSQL数据库.两者在分布式.微服务架构中使用率极高,本文将用实例介绍如何在Springboot中整合Mon ...

  8. 字符串的常用操作和方法(Python入门教程)

    字符串的常用操作 很好理解 字符串可以用 ' + ' 连接,或者乘一个常数重复输出字符串 字符串的索引操作 通过一对中括号可以找到字符串中的某个字符 可以通过正负数双向操作噢 用一个中括号来实现 为什 ...

  9. D - Yet Another Monster Killing Problem

    题目连接: https://codeforces.com/contest/1257/problem/D 题目大意: n个怪兽,m个英雄,每个怪兽有一定的能力值,每个英雄有一定的能力值和一定的耐力值.耐 ...

  10. Mac os Pycharm 中使用Stanza进行实体识别(自然语言处理nlp)

    stanza 是斯坦福开源Python版nlp库,对自然语言处理有好大的提升,具体好在哪里,官网里面都有介绍,这里就不翻译了.下面放上对应的官网和仓库地址. stanza 官网地址:点击我进入 sta ...