插入排序、选择排序、快速排序、归并排序

目录

冒泡排序

插入排序

选择排序

快速排序

归并排序


个人简单理解

  • 冒泡:找到当前索引最小值(最大值),然后依次往后找最n小只(最n大值)

  • 插入:与前面的有序数组比较

  • 选择:与当前数,后面的数比较
  • 快排:5个变量(四个边界,一个基准值用于比较。从右基准找到比基准值小的数,就放到左边;从左基准找到比基准值大的数,就放到右边),类似于二分查找,逐渐缩小范围(除基准值以外的左右两个范围)

冒泡排序

两个for循环,找到当前索引应该存放的值,如果两个数值不相同就进行交换。比如一个数组中最小值是0,那么索引0存放的值就是数值0

public static void BubbleSort(int[] nums)
        {
            for (int i = 0; i < nums.Length; i++)
            {
                for (int j = i+1; j < nums.Length; j++)
                {
                    if (nums[i] > nums[j])
                    {
                        int temp = nums[i];
                        nums[i] = nums[j];
                        nums[j] = temp; 
                    }
                }
            }
        }

插入排序

  • 升序:将当前数字取出来,和前面的有序数字进行比较,如果比前面的数字小就进行交换
  • 我使用for+while循环,通过while循环可以避免冗余(如果在有序数组中,已经比前面一个数字大了,就不用继续进行比较了)
static void Main(string[] args)
        {
            //测试数据
            int[] array = { 1, 4, 2, 43, 5, 61, 89, 34, 67, 32, 40 };
            //将数据排序
            InsertSort(array);
            //排序后的数据
            foreach (int arr in array)
            {
                Console.WriteLine(arr);
            }
        }


        public static void InsertSort(int[] nums)
        {
            for (int i = 1; i < nums.Length; i++)
            {
                int temp = nums[i];
                int j = i - 1;
                //索引 >= 0,当前数小于前面的数
                while (j >= 0 && temp < nums[j])
                {
                    nums[j + 1] = nums[j];
                    j--;//方便下一次比较
                }
                //数值交换完,将最前面空着的数填充
                nums[j + 1] = temp;
            }
        }

选择排序

  • 先将索引0赋值为minIndex(最小数),然后与当前位置后的数逐一比较,如果比minIndex索引小,那么就交换索引
  • 比较完后,判断当前索引是否等于minIndex索引,如果不相等,两个数就交换值(位置)
static void Main(string[] args)
        {
            //测试数据
            int[] array = { 1, 4, 2, 5 };
            //将数据排序
            QuickSort(array);
            //排序后的数据
            foreach (int arr in array)
            {
                Console.WriteLine(arr);
            }
        }


        public static void QuickSort(int[] arr)
        {
            for (int i = 0; i < arr.Length; i++)
            {
                int minIndex = i;//最小数索引
                for (int j = i+1; j < arr.Length; j++)
                {
                    //找到最小数,进行交换索引
                    if (arr[minIndex] > arr[j])
                    {
                        minIndex = j;
                    }
                }

                //i索引不是最小数,进行交换索引
                if (minIndex != i)
                {
                    int temp = arr[i];
                    arr[i] = arr[minIndex];
                    arr[minIndex] = temp;
                }
            }
        }

快速排序

简单理解

理论

  • 选取基准,产生左右标识,左右比基准,满足则换位
  • 排完一次,基准定位
  • 左右递归,直到有序

我自己的简单理解

  • 确定左右标识、左右基准、基准值(一开始值为左基准值,也就是下图的3)
  • 当前值为基准值,然后与左右基准值进行比较,通过换位确定基准值应该存在的位置

交换位置:基准值为3,从右基准的位置开始找比3小的数放到左边;然后再从左基准开始找比3大的数放到右边。

  • 缩小范围继续比较(除基准值以外,确定两个区间范围)

static void Main(string[] args)
        {
            //测试数据
            int[] array = { 1, 4, 2, 5 };
            //将数据排序
            QuickSort(array,0,array.Length  - 1);
            //排序后的数据
            foreach (int arr in array)
            {
                Console.WriteLine(arr);
            }
        }


        public static void QuickSort(int[] arr, int left, int right)
        {
            if (left >= right) return;
            int tempLeft, tempRight, temp;
            tempLeft = left;
            tempRight = right;
            temp = arr[left];

            while (tempLeft != tempRight)
            {
                while (tempLeft < tempRight && arr[tempRight] < temp)
                {
                    tempRight--;//移动右标识
                }
                arr[tempLeft] = arr[tempRight];//处理小于基准值的数,移动到左边

                while (tempLeft < tempRight && arr[tempLeft] > temp)
                {
                    tempLeft++;//移动左标识
                }
                arr[tempRight] = arr[tempLeft];//处理大于基准值的数,移动到右边
            }
            arr[tempLeft] = temp;//基准值通过排序,确定它应该放的位置

            //缩小范围处理,除基准值之外的范围
            QuickSort(arr, left, tempLeft - 1);
            QuickSort(arr, tempRight + 1, right);
        }

归并排序

原理:

  1. 基础排序
  2. 递归分解数组

图解:把一个数组一直拆分,最后数组长度小于2,就停止拆分

代码:基础排序

using System;



namespace 归并

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.WriteLine("程序内部会先分割数组,在对数组进行排序");

            Console.WriteLine("自己在写归并的时候,可以先写排序函数,再写分割数组函数");

            int[] arr = new int[] { 8, 7, 1, 5, 4, 2, 6, 3, 9 };//申明一个数组,待会进行排序

            //需要申明一个新的数组用来接收排序完的数组,原数组虽然进行了排序,但只改变了原数组的地址(并非原数组的值)

            //数组是引用类型,原数组的值在输出的时候不会受到改变

            int[] arr2 = Merge(arr);

            //打印输出数组排序

            for (int i = 0; i < arr2.Length; i++)

            {

                Console.WriteLine(arr2[i]);

            }

        }



        //基础排序函数  函数中的static不是必要的,是因为这个C#控制台程序的原因,不然写起来不方便

        public static int[] Sort(int[] left,int[] right)

        {

            //新数组,用于存储排序后的数据

            int[] array = new int[left.Length + right.Length];

            //左数组的索引

            int leftIndex = 0;

            //右数组的索引

            int rightIndex = 0;

            for (int i = 0; i < array.Length; i++)

            {

                //如果left数组的数据都排序完了,就直接将right数组的数据放入新数组

                if (leftIndex>=left.Length)

                {

                    array[i] = right[rightIndex];

                    //索引加加,如果right数组有2,1;left数组有7,3。1先存到array数组,在继续循环

                    //会将right数组中的2和left数组中的数据进行判断

                    rightIndex++;

                }

                //如果right数组的数据都排序完了,就直接将left数组的数据放入新数组

                //这个else if很重要,这四个判断语句只会执行其中的一条。如果都是if而不是elseif,那么就会去判断所有的if

                else if (rightIndex >= right.Length)

                {

                    array[i] = left[leftIndex];

                    leftIndex++;

                }

                //如果left数组的数据比右数组的数据要小,那么将left数组的数据放入新数组

                else if (left[leftIndex] < right[rightIndex])

                {

                    array[i] = left[leftIndex];

                    leftIndex++;

                }

                else

                {

                    //如果right数组的数据比右数组的数据要小,那么将right数组的数据放入新数组

                    array[i] = right[rightIndex];

                    rightIndex++;

                }

            }

            //将排序好的数组返回出去

            return array;

        }



        //递归分割数组

        public static int[] Merge(int[] array)

        {

            //结束递归的条件,不然递归会无限循环

            //当数组长度小于2时,就不在分割

            if (array.Length < 2)

                return array;



            //分割数组

            int mid = array.Length / 2;

            //分割后的左数组

            int[] left = new int[mid];

            //分割后的右数组

            int[] right = new int[array.Length - mid];



            for (int i = 0; i < array.Length; i++)

            {

                //left数组进行赋值

                if (i < mid)

                    left[i] = array[i];

                //right数组进行赋值  假如array数组一共有9个数,right数组长度为5。i为5时right就会进行赋值

                //5 - 4(4是mid的值),对right数组中的第一个值进行赋值

                else

                    right[i - mid] = array[i];

            }

            //利用递归,分割数组

            //数组假如有9个数,一直除以2。当数组长度小于2时,才会进行排序

            return Sort(Merge(left), Merge(right));

        }

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值