欢迎光临散文网 会员登陆 & 注册

一周刷爆LeetCode,算法大神左神(左程云)耗时100天打造算法与数据...

2023-07-02 14:18 作者:栽在这  | 我要投稿

1.时间复杂度:常数的计算次数(读取,交换都算一次)按照最坏情况算

随机数据

    private static List<int> anyMath()

    {

      List<int> maths = new List<int>();

      Random ran = new Random();

      for (int i=0; i<10; i++)

      {

        //Random在循环中的随机数相同,所以需要在循环外创建

        maths.Add(ran.Next(0,10));

      }

      return maths;

    }

主函数:

    static void Main(string[] args)

    {

      List<int> list = anyMath();

      foreach (int i in list)

      {

        Console.Write(i+" ");

      }

      Console.WriteLine("源数据");

      int[] list2 = list.ToArray();

      int[] list3 = list.ToArray();

      int[] list4 = list.ToArray();

      int[] list5 = list.ToArray();

      int[] list6 = list.ToArray();

      int[] list7 = list.ToArray();

         int[] list8 = list.ToArray();

      Array.Sort(list2);

      foreach (int i in list2)

      {

        Console.Write(i + " ");

      }

      Console.WriteLine("函数数据");

      selectSort(list3);//

      maoPaoSort(list4);//

      guiBinSort(list5);//

      insertSort(list6);

      quikeSort(list7);//

      heapSort(list8);

      Console.ReadLine();


    }


选择排序:最小归左

    private static int[] selectSort(int[] list)

    {

      int min = list[0];

      for(int i=0;i<list.Length-1;i++)

      {

        for(int j=i+1; j<list.Length; j++)

        {

          if (list[i] > list[j])

            swap(ref list[i],ref list[j]);

          else continue;

        }

      }

      foreach (int i in list)

      {

        Console.Write(i + " ");

           }

      Console.WriteLine("选择排序");

      return list;

    }

冒泡排序:最大归右

    private static int[] maoPaoSort(int[] list)

    {

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

      {

        for(int j=0;j<list.Length-i-1;j++)

        {

          if (list[j] > list[j + 1])

          {

            swap(ref list[j], ref list[j+1]);

          }

          else continue;

        }

      }

      foreach (int i in list)

      {

        Console.Write(i+ " ");

      }

      Console.WriteLine("冒泡排序");

      return list;

    }

异或,不进位相加,a,b的地址不可相同

    private static void swap(ref int a,ref int b)

    {

      //a,b同地址崩溃

      a ^= b;b ^= a;a ^= b;

    }

    private static void change(ref int a,ref int b)

    {

      int temp=a;

      a = b;b = temp;

    }

2.

master公式算递归时间复杂度,递归的子问题规模相同,其中例子a=2,b=2,d=0

归并排序,将数组分成两份,使两份数据分别有序,然后使用"双指针"比较两份数据的首数字大小,比较大小后将其拷贝如原数组,相比选择,冒泡排序等,没有浪费比较的结果,选择等的比较每次都只能比较出一个位置的数字,归并排序始终有序。部分也有序,不会浪费。

    private static int[] guiBinSort(int[] list)

    {

      list=masterSort(list);

      foreach (int i in list)

      {

        Console.Write(i + " ");

      }

      Console.WriteLine("归并排序");

      return list;

    }

    private static int[] masterSort(int[] list)

    {

      List<int> list4 = new List<int>();

      if (list.Length== 1)

      {

        return list;

      }

      else

      {

        int[] list2 = masterSort(list.Take(list.Length / 2).ToArray());

        int[] list3 = masterSort(list.Skip(list.Length / 2).ToArray());

        for(int i=0,j=0;i<list2.Length||j<list3.Length;)

        {

                  if(i==list2.Length)

          {

            list4.Add(list3[j++]);

            continue;

          }

          else if(j==list3.Length)

          {

            list4.Add(list2[i++]);

            continue;

          }

          if (list2[i] <= list3[j])

            list4.Add(list2[i++]);

          else list4.Add(list3[j++]);

              }

        return list4.ToArray();

      }


    }

快速排序:随机选择数组中的一个数字,然后将其与数组最后一位交换顺序,然后遍历数组,如果当前比较数字较小,那么数字不动,左边区域大小加一。如果数字较大,和末尾被比较数字换位置,末尾的范围加一(指针向前指一位)。相等则不管。

    private static int[] quikeSort(int[] list)

    {

      list1.Clear();

      list = quikelySort(list);

      foreach (int i in list)

      {

        Console.Write(i + " ");

      }

      Console.WriteLine("快速排序");

      return list;

    }

    private static int[] quikelySort(int[] list)

    {

      if (list.Length == 0 || list.Length == 1)

      {

        canAdd = true;

        return list;

      }

      else if(list.Length == 2)

      {

        if (list[0] > list[1])

          change(ref list[0], ref list[1]);

        canAdd = true;

        return list;

      }

      foreach(var li in list.GroupBy(x=>x))

      {

        if (li.Count() == list.Length)

        {

          canAdd = true;

          return list;

        }

      }

      byte[] buffer = Guid.NewGuid().ToByteArray();

      Random random = new Random(BitConverter.ToInt32(buffer,0));//伪随机,为其参数添加一个较可靠的因子

      change(ref list[list.Length - 1], ref list[random.Next(0, list.Length)]);

      for(int i=0,L=0,R=0;i<list.Length;)//R=list.Length-1-i

      {

        if(L+R==list.Length-1)

        {

          canAdd = false;

          change(ref list[list.Length-1],ref list[L]);

          //若数据为0,2,0,3,并不会运行到Length<=2处,内部无序,递归---fail

          //1.判断返回长度---影响前几次数据

          //2.判断数据的最后一位是否最大

          //不设除0 1 2数字的出口。----fail

          //quikelySort(list.Take(L + 1).ToArray());

          int[] list2 = quikelySort(list.Take(L + 1).ToArray());//1 1 1 无法从递归中出来

          //同理 1 1 1 1 1

          //每次递归数据都会增加,判断数据是否有序,若有序则加入

          //若数据无效,则跳过此段循环

          if(canAdd)

          {

            for (int j = 0; j < list2.Length; j++)

              list1.Add(list2[j]);

            canAdd = false;

          }

          int[] list3 = quikelySort(list.Skip(L + 1).ToArray());

          if(canAdd)

          {

            for (int j = 0; j < list3.Length; j++)

              list1.Add(list3[j]);

            canAdd = false;

          }

          return list1.ToArray();

        }

        if (list[i] > list[list.Length - 1])

        {

          R++;

          change(ref list[i], ref list[list.Length-1-R]);

        }

        else

        {

          i++;L++;

        }

      }

      return list1.ToArray();

    }

插入排序:每次数字与其前面所有数据比较,小于则换位置,知道前面没有更大数字

    private static int[] insertSort(int[] list)

    {

      list=InsertSort(list);

      foreach (int i in list)

      {

        Console.Write(i + " ");

      }

      Console.WriteLine("插入排序");

      return list;

    }

    private static int[] InsertSort(int [] list)

    {

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

      {

        int k = i-1;

        for(int j=i;k>=0&&j<list.Length;k--,j--)

        {

          int temp = list[j];

          if (list[k] > list[j])

          {

            list[j] = list[k];list[k] = temp;

          }

          continue;


        }

      }

             return list;

    }

3.堆排序,大根堆--父永远比子大,左子树的序号减一除二几位父节点的序号,右子树则 减二除二,heapInsert,

    private static int[] heapSort(int[] list)

    {

      //无需定义树结构!数据的下表代表其在树中的位置。

      //设左子树的位置为n,左子树的父节点为(n-1)/2

      //设右子树的位置为n,右子树的父节点为(n-2)/2

      list = heapInsert(list, list.Length);

      foreach (int i in list)

      {

        Console.Write(i + " ");

      }

      Console.WriteLine("堆排序");

      return list;

    }

    public class Tree

    {

      public int val;

      public Tree leftChild;

      public Tree rightChild;

      public Tree(int val = 0, Tree leftChild = null, Tree rightChild = null)

      {

        this.val = val;

        this.leftChild = leftChild;

        this.rightChild = rightChild;

      }

    }

    private static int[] heapInsert(int[] list, int Length)

    {

      if (Length == -1||Length==0)

        return list;

      for (int i = Length - 1; i > 0; i -= 2)

      {

        //右子树

        if (i % 2 == 0)

        {

          int temp = list[(i - 2) / 2] > (list[i - 1] > list[i] ? list[i - 1] : list[i]) ? list[(i - 2) / 2] : list[i - 1] > list[i] ? list[i - 1] : list[i];

          if (temp == list[(i - 2) / 2])

            continue;

          else if (temp == list[i])

            swap(ref list[i], ref list[(i - 2) / 2]);

          else

            swap(ref list[i - 1], ref list[(i - 2) / 2]);

        }

        //左子树

        else

        {

          if (i == Length - 1)

          {

            if (list[i] > list[(i - 1) / 2])

              swap(ref list[i], ref list[(i - 1) / 2]);

          }

          else

          {

            int temp = list[(i - 1) / 2] > (list[i + 1] > list[i] ? list[i + 1] : list[i]) ? list[(i - 1) / 2] : list[i + 1] > list[i] ? list[i + 1] : list[i];

            if (temp == list[(i - 1) / 2])

              continue;

            else if (temp == list[i])

              swap(ref list[i], ref list[(i - 1) / 2]);

            else

              swap(ref list[i + 1], ref list[(i - 1) / 2]);

          }

        }

      }

      change(ref list[0], ref list[Length - 1]);

      heapInsert(list, Length-1);

      return list;

    }


4.桶排序,找到所有数字中最大数字的位数,如:10为两位数,将其他诸如1,2的数字补齐两位-01,02等,准备最多10个桶,所有数字一共进桶,出桶两次,首先根据所有数字的个位进桶---依次进入下标为0-9的桶中,按照桶的顺序出通,然后根据十位进桶,出桶,排序就完成了。

5.计数排序

6.基数排序

/*


*/

一周刷爆LeetCode,算法大神左神(左程云)耗时100天打造算法与数据...的评论 (共 条)

分享到微博请遵守国家法律