首页 > 编程语言 >c#学习笔记----------------c#简单算法之排序算法

c#学习笔记----------------c#简单算法之排序算法

时间:2023-08-05 19:44:40浏览次数:44  
标签:---------------- nums c# ++ Length int 算法 test array

 

排序算法

参考文章:https://blog.csdn.net/weixin_61361738/article/details/128794945

冒泡排序

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string str=Console.ReadLine();
            string[] strarr = str.Split(',');
            int[] intarr= new int[strarr.Length];
            for (int i = 0; i < strarr.Length; i++)
            {
                intarr[i] = Convert.ToInt32(strarr[i]);
            }
            for(int i = 0;i<intarr.Length-1; i++)// 外层循环控制循环次数
            {
                for(int j = 0;j<intarr.Length-1-i; j++)//内层循环用于交换相邻要素
                {
                    int temp;
                    // if (split[j] < split[j + 1])倒序排列
                    if (intarr[j] > intarr[j + 1])
                    {
                        temp = intarr[j + 1];
                        intarr[j + 1] = intarr[j];
                        intarr[j] = temp;
                    }
                }
            }
            string result = "";
            foreach(int i in intarr)
            {
                result += i + ",";
            }
            Console.WriteLine(result);
            Console.ReadLine();
        }
    }
}

选择排序

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int[] test = { 3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48 };
            for(int i = 0; i < test.Length; i++)
            {
                // 找无序区中最小的元素 
                int minindex = i;
                for(int j=i+1; j<test.Length; j++)
                {
                    if (test[j] < test[minindex])
                    {
                        minindex = j;
                    }
                }
                //执行完上面的循环
                //minindex就是无序区最小元素的索引
                //把最小元素和有序区交换位置
                int temp = test[i];
                test[i] = test[minindex];
                test[minindex] = temp;
            }
            foreach(int item in test)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }
}

插入排序

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int[] test = { 3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48 };
            for (int i = 0; i < test.Length - 1; i++)//最后一位不用排序
            {
                int curNum = test[i + 1];     // 无序区的第一个元素 
                int idx = i;    //有序区的最后一个元素的索引

                while (idx >= 0 && test[idx] > curNum)
                {
                    test[idx + 1] = test[idx];  // 把有序区的元素往后挪一位
                    idx -= 1;
                }
                test[idx + 1] = curNum;
            }
            foreach (int item in test)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }
}

快速排序

using System.Collections.Concurrent;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int[] test = { 3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48 };
            QuickSort2(test, 0, test.Length - 1);
            foreach (int item in test)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }

        /*第二种方法:用数组计算,此方法无需生成新的数组,
         * 而是人为的将一个数组划分两个区域.
         * 数组大了之后计算速度比较快
         */
        //将一个数组看为两个,第一个小数组起点为原数组的起点
        //第二个大数组起点为原数组的终点
        public static void QuickSort2(int[] list, int left, int right)
        {
            if (left >= right)//若数组的左端下标大于或等于右端下标,则表明数组为一或空
            {
                return;//结束方法
            }
            int i, j, temp;
            i = left;
            j = right;
            temp = list[left];//将数组中的第一个元素当做基准值
            while (i != j)//当i=j时,表明将大于基准值的数和小于基准值的数全部分开
            {
                while (list[j] >= temp && i < j)
                {
                    j--;
                }
                while (list[i] <= temp && i < j)
                {
                    i++;
                }
                //交换数组中大于基准值的数和小于基准值的数
                if (i < j)
                {
                    int t = list[i];
                    list[i] = list[j];
                    list[j] = t;
                }
            }
            //将基准值放到大数组和小数组中间
            list[left] = list[i];
            list[i] = temp;
            QuickSort2(list, i + 1, right);
            QuickSort2(list, left, i - 1);

        }
    }
}

归并排序

public class Solution
{
    // 合并
    public static int[] merge(int[] left, int[] right)
    {
        // 最终返回一个合并好的有序的数组
        // 定义两个变量,分别代表当前left与right的未添加进有序数组的第一个元素
        int leftIndex = 0, rightIndex = 0;
        List<int> res = new List<int>();        
       
        while (leftIndex < left.Length && rightIndex < right.Length)
        {
            //左边数组的元素小于右边数组 
            if (left[leftIndex] <= right[rightIndex])
            {
                // 把左边元素添加到有序区中 
                res.Add(left[leftIndex]);
                // 索引往后移
                leftIndex ++; 
            }
            else
            {
                // 把右边元素添加到有序区中 
                res.Add(right[rightIndex]);
                // 索引往后移 
                rightIndex ++; 
            }
        }

        // 把剩余的未添加的元素全部添加到有序数组后面
        foreach (int item in right[rightIndex..])    
        {
            res.Add(item);
        }

        // 为什么可以直接添加?因为left,right本身就是一个有序数组
        foreach (int item in left[leftIndex..])      
        {
            res.Add(item);
        }
        // 如果说left_idx走完了,right还剩一些元素,说明right剩下的元素全部都比有序数组的最后一个元素要大
        return res.ToArray();
    }

    // 归并排序
    public static int[] mergeSort(int[] nums)
    {
        //数组不能再分了
        if (nums.Length <= 1)
            return nums;
        int mid = nums.Length / 2;      // 求出数组的中间位置 
        
        int[] left = mergeSort(nums[..mid]);
        int[] right = mergeSort(nums[mid..]);
   
        // 合并
        return merge(left, right); 
    }

    // 归并排序 
    static void Main(string[] args)
    {
        int[] nums = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48}; 
        int[] result = mergeSort(nums);
        foreach(int item in result)
        {
            Console.WriteLine(item);
        }
    }
}

计数排序

public class Program
{
    // 计数排序
    public static void CountingSort(int[] array)
    {
        // 长度小于等于0直接return
        if (array.Length <= 0) 
            return;

        int min = array[0];     
        int max = min;
        // 找出数组最大元素和最小元素 
        foreach (int item in array)
        {
            if (item > max)
            {
                max = item;
            }
            else if (item < min)
            {
                min = item;
            }
        }

        // 把所有元素存入counting数组 
        int[] counting = new int[max - min + 1];
        for (int i = 0; i < array.Length; i++)
        {
            counting[array[i] - min] += 1;
        }

        int index = -1;
        for (int i = 0; i < counting.Length; i++)
        {
            for (int j = 0; j < counting[i]; j++)
            {
                index++;
                array[index] = i + min;
            }
        }
    }


    public static void Main(string[] args)
    {
        int[] array = { 43, 69, 11, 72, 28, 21, 56, 80, 48, 94, 32, 8 };
        CountingSort(array);

        foreach(int item in array)
        {
            Console.WriteLine(item);
        }
    } 
}

基数排序

public class Program
{
    // 基数排序 
    public static void RadixSort(int[] array, int bucketNum)
    {
        int maxLength = MaxLength(array);

        //创建bucket时,在二维中增加一组标识位,
        //其中bucket[x, 0]表示这一维所包含的数字的个数
        //通过这样的技巧可以少写很多代码
        int[,] bucket = new int[bucketNum, array.Length + 1];

        for (int i = 0; i < maxLength; i++)
        {
            foreach (var num in array)
            {
                int bit = (int)(num / Math.Pow(10, i) % 10);
                bucket[bit, ++bucket[bit, 0]] = num;
            }

            for (int count = 0, j = 0; j < bucketNum; j++)
            {
                for (int k = 1; k <= bucket[j, 0]; k++)
                {
                    array[count++] = bucket[j, k];
                }
            }

            //最后要重置这个标识
            for (int j = 0; j < bucketNum; j++)
            {
                bucket[j, 0] = 0;
            }

        }
    }

    private static int MaxLength(int[] array)
    {
        if (array.Length <= 0) 
            return 0;
            
        int max = array.Max();      // 取出数组的最大值 
        return (int)Math.Log10(max) + 1;    // 取出位数 
    }


    public static void Main(string[] args)
    {
        int[] array = { 3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
        RadixSort(array, 10);
        foreach (int item in array)
        {
            Console.WriteLine(item);
        }
    }
}

桶排序

public class Program
{
    // 桶排序
    static void BucketSort(int[] array, int bucketsize = 5)
    {
        int max = array.Max(), min = array.Min();               // 最大值与最小值
        int bucketnums = (max - min) / bucketsize + 1;           // 分配的桶数量

        List<List<int>> buckets = new List<List<int>>();
        // 生成桶
        for (int i = 0; i < bucketnums; i++)
        {
            buckets.Add(new List<int>());
        }

        //将数组的元素放入桶中,并保证桶里是有序的        
        for (int i = 0; i < array.Length; i++)
        {
            int bucketIndex = (array[i] - min) / bucketsize;
            buckets[bucketIndex].Add(array[i]);
        }

        int index = 0;
        for (int i = 0; i < buckets.Count; i++)
        {
            buckets[i].Sort();      // 对生成的每个桶排序 
            for (int j = 0; j < buckets[i].Count; j++)
            {
                array[index++] = buckets[i][j];
            }
        }
    }
    
    static void Main(string[] args)
    {
        int[] test = { 3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48 };
        BucketSort(test); 
        
        foreach(int item in test)
        {
            Console.WriteLine(item);
        }
    }
}

堆排序

class Program
{
    // 堆排序 
    public static void HeapSort(int[] nums)
    {
        //将最大的值推到堆顶
        //x根据最后一个子节点的位置计算出父节点
        int x = Convert.ToInt32(Math.Floor(Convert.ToDouble((nums.Length - 2) / 2)));
        for (int i = x; i >= 0; i--)
        {
            //如果子元素只存在左子元素时, 让右子元素等于左子元素
            while (nums[i] < nums[i * 2 + 1] || nums[i] < nums[(i * 2 + 2) > (nums.Length - 1) ? (i * 2 + 1) : i * 2 + 2])
            {
                if (nums[i * 2 + 1] >= nums[(i * 2 + 2) > (nums.Length - 1) ? (i * 2 + 1) : i * 2 + 2])
                {
                    int index = nums[i];
                    nums[i] = nums[i * 2 + 1];
                    nums[i * 2 + 1] = index;
                }
                else
                {
                    int index = nums[i];
                    nums[i] = nums[i * 2 + 2];
                    nums[i * 2 + 2] = index;
                }
            }
        }
        //输出堆顶最大的元素
        int max = nums[0];
        nums[0] = nums[nums.Length - 1];
        Console.WriteLine(max);
        //将数组中的最后一个元素删除
        int[] num = new int[nums.Length - 1];
        for (int j = 0; j < nums.Length - 1; j++)
        {
            num[j] = nums[j];
        }

        Adjust(num);
    }


    public static void Adjust(int[] nums)
    {
        if (nums.Length > 1) HeapSort(nums);
        else Console.WriteLine("{0}\t", nums[0]);
    }

    static void Main(string[] args)
    {
        int[] nums = new int[] { 3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48 };
        Adjust(nums);
    }
}

希尔排序

public class Program
{
    // 希尔排序 
    public static void shellSort(int[] nums)
    {
        int n = nums.Length;    // 数组的长度 
        int gap = n / 2;    // 设定一个增量gap 
        
        while(gap >= 1)
        {
            // 分组
            for(int i = gap; i < n; i++) 
            {
                int curNum = nums[i];   // 当前要插入的无序区的元素的值
                int idx = i - gap;      // 当前元素所在小组的有序区的最后一个元素的索引 
                while (idx >= 0 && curNum < nums[idx])      // 插入排序
                {
                    nums[idx + gap] = nums[idx];
                    idx -= gap;
                }
                nums[idx+gap] = curNum; 
            }
            gap /= 2;   // 缩小增量 
        }
    }
     
   
    static void Main(string[] args)
    {
        int[] test = { 3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48 };
        shellSort(test); 
        foreach(int item in test)
        {
            Console.WriteLine(item);
        }
    }
}

 

查找重复字母算法

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string str=Console.ReadLine();
            int[] countArray = new int[26];
            string c = "";
            for(int i = 0; i < str.Length; i++)
            {
                countArray[str[i] - 'a'] = countArray[(str[i] - 'a')] + 1;
            }
            for(int i = 0;i < str.Length; i++)
            {
                if(countArray[str[i] - 'a'] > 1)
                {
                    if (!c.Contains(str[i])) 
                    {
                        c += str[i].ToString() + ",";
                    }
                }
            }
            if(string.IsNullOrEmpty(c))
            {
                c = "null";
            }
            Console.WriteLine(c);
            Console.ReadKey();
        }
    }
}

 

排序算法平均时间复杂度最好情况最坏情况空间复杂度稳定性
冒泡排序 O(n2) O(n) O(n2) O(1) 稳定
选择排序 O(n2) O(n2) O(n2) O(1) 不稳定
插入排序 O(n2) O(n) O(n2) O(1) 稳定
快速排序 O(nlogn) O(nlogn) O(n2) O(logn) 不稳定
随机快速排序 O(n2) O(nlgn) O(n2) O(1) 不稳定
归并排序 O(nlogn) O(nlogn) O(nlogn) O(n) 稳定
计数排序 O(n + k) O(n + k) O(n + k) O(k) 稳定
基数排序 O(n × \times ×k) O(n × \times ×k) O(n × \times ×k) O(n + k) 稳定
桶排序 O(n + k) O(n + k) O(n2) O(n + k) 稳定
堆排序 O(nlogn) O(nlogn) O(nlogn) O(1) 不稳定
希尔排序 O(nlogn) O(nlog2n) O(nlog2n) O(1) 稳定

 

 

标签:----------------,nums,c#,++,Length,int,算法,test,array
From: https://www.cnblogs.com/misakayoucn/p/17608482.html

相关文章

  • GFOJ-1808 牛奶访客
    题面题目描述FarmerJohn计划建造\(N\)(\(1\leqN\leq10^5\))个农场,用\(N−1\)条道路连接,构成一棵树(也就是说,所有农场之间都互相可以到达,并且没有环)。每个农场有一头奶牛,品种为更赛牛或荷斯坦牛之一。FarmerJohn的\(M\)个朋友(\(1\leqM\leq10^5\))经常前来拜访他。......
  • .NET 个人博客-首页排版优化-2
    个人博客-首页排版优化-2原本这篇文章早就要出了的,结果之前买的服务器服务商跑路了,导致博客的数据缺失了部分。我是买了一年的服务器,然后用了3个月,国内跑路云太多了,然后也是花钱重新去别的服务商买了一台服务器,这次只买了一个月,先试试水。优化计划置顶3个且可滚动或切换推......
  • php简明手册(1)
    目录安装安装基于linuxsudodnfinstallphp安装postgresqlf支持sudodnfinstallphp-pgsql*基于源码编译tarzxfphp-x.x.xcd../php-x.x.x./configure--enable-fpm--with-mysqlmakesudomakeinstall创建配置文件,并将其复制到正确的位置cpphp.ini-deve......
  • 第五周总结
      这周主要还是考驾照练车,我们这边暴雨持续了几天。  下周准备看一下《天道》,之前刷抖音的时候看过一遍,但是内容可能不太精细。  在这几周的学习中,学习进度也是很缓慢,也没有学习到什么实质性的知识,这次总结就做一下下周的计划。首先就是完成《天道》的作业任务,以及......
  • sqlalchemy 自动过滤逻辑删除(软删除)记录
     先创建一个基类,用来表示某个类支持逻辑删除classSoftDeleteModel:'''逻辑删除基类用来实现逻辑删除。继承这个基类的子类需要在数据库的列中存在deleted_at列,类型为varchar。'''deleted_at:Mapped[str]=mapped_column(String(50),default=None......
  • DOM编程
    DOM编程介绍DOM编程是指使用JavaScript与HTML文档中的DOM(文档对象模型)进行交互的过程。文档:整个HTML网页文档对象:网页中的每一部分都转换为了对象模型:使用模型表示对象之间的关系DOM是HTML文档的树状结构表示,它允许开发者使用JavaScript来访问、操作和修改HTML元素、......
  • 单片机基本知识
    1.芯片引脚Vdd和VssVdd=VoltageDrain-DrainVss=VoltageSource-Source     .    2.晶振电路图 2.GPIOGeneralPurposeInput/Output通用目的输入输出输入:通过IO引脚读取外部输入电平的高或低输出:通过IO引脚向外输出高电平或者低电平 输出:......
  • 【LGR-150-Div.2】洛谷 8 月月赛 I & RiOI Round 2
    比赛实况赛前看了眼难度分布,红橙黄绿,感觉随便杀(爆我)顺序开题,先看A题,没仔细读,一眼以为单次操作只能翻转一位,写了个十进制转二进制找不同,结果WA了。再看了一眼题,发现题干定义的操作可以一次操作很多位,然后一个操作是把0变1,另一个是把1变0。所以只需要看两个数二进制对......
  • 做题记录
    P1280尼克的任务题意:题目传送门思路:很明显这一道dp题目,考虑dp[i]的含义,容易想到表示1~n时间内摸鱼时间的最大值。接下来考虑转移方程。考虑在时间为i时到达岗位开始工作,即在岗时间为i~n。此时如果有任务且不在工作状态,即可考虑从任务结束时间转移过来(在结束时间时未已在任务......
  • 面向切面编程
    使用AOP的优势:提高代码的可重用性业务代码编码更简洁业务代码维护更高效业务功能拓展更便捷AOP的使用:1)方式一:2)方式二:使用自定义注解  ......