zoukankan      html  css  js  c++  java
  • C#算法收集

     很多程序员朋友都抱怨着算法的枯燥,同样也说着算法就像初中高中的物理化学,现在学的计算机和他们挂个毛的边。 也许我是个另类,我觉得算法就是告诉你,怎么佯作,才能提高你的程序效率。通俗点说:你有两台电脑,打游戏的时候你会使用非常卡的那台还是流畅的那台?当然两台的cpu和Gpu完全是不同的,如果你不去了解cpu和Gpu,你能知道那台电脑打起游戏来比较爽吗? 
    废话少说,切入主题。 从前,上山有座庙,庙里有个老和尚,老和尚在说:从前,上山有座庙,庙里有个老和尚,老和尚在说:从前,上山有座庙,庙里有个老和尚,老和尚在说:(Repeating……)。
    这就是一个递归。当然在数学里,我们把它叫做“菲波拉契数” Eg:计算1,1,2,3,5,8....... 第30位值。

    1.递归算法:

    思想:在函数或子过程的内部,直接或者间接地调用自己的算法。

    递归算法解决问题的特点:
      (1) 递归就是在过程或函数里调用自身。
      (2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
      (3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。所以一般不提倡用递归算法设计程序。
      (4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。所以一般不提倡用递归算法设计程序。
    让我们先考虑下: 
    序号 结果
    0------1
    1------1
    2------2
    3------3
    4------5
    5------8



    30------???
    可以清楚的看出他们的对应关系:结果小于2且大于等于0的时候,结果为1,。序号大于等于2时,其结果,等于(结果-1+结果-2):
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace ArithMetic
     7 {
     8     class Program
     9     {
    10         static void Main(string[] args)
    11         {
    12             //计算数组1,1,2,3,5,8.......第30位的值
    13             Console.WriteLine(RecursiveAlgorithm.Fibonacci(3));
    14             Console.ReadKey();
    15         }
    16         //1.递归算法 Eg:计算1,1,2,3,5,8....... 第30位值
    17         class RecursiveAlgorithm//递归算法类
    18         {
    19             /// <summary>
    20             /// 菲波拉契数
    21             /// </summary>
    22             /// <param name="i"></param>
    23             /// <returns></returns>
    24             public static int Fibonacci(int i)
    25             {
    26                 if (i < 0)
    27                     return 0;
    28                 if (i >= 0 && i < 2)
    29                     return 1;
    30                 else
    31                     return Fibonacci(i - 1) + Fibonacci(i - 2);
    32             }
    33         }
    34     }
    35 }

     2 .冒泡排序算法

     思想:

    冒泡排序算法:将n个记录看作按纵向排列,每趟排序时自下至上对每对相邻记录进行比较,若次序不符合要求(逆序)就交换。每趟排序结束时都能使排序范围内关键字最小的记录象一个气泡一样升到表上端的对应位置,整个排序过程共进行n-1趟,依次将关键字最小、次小、第三小…的各个记录“冒到”表的第一个、第二个、第三个…位置上。

       初态      第1趟   第2趟  第3趟  第4趟  第5趟  第6趟  第7趟
        38        12      12      12      12      12      12      12                               
        20        38      20      20      20      20      20      20 
        46        20      38      25      25      25      25      25 
        38        46      25      38      38      38      38      38 
        74        38      46      38      38      38      38      38 
        91        74      38      46      46      46      46      46 
        12        91      74      74      74      74      74      74
        25        25      91      91      91      91      91      91

     一般来说,网上很多的源码,都没有加判断:判断是否进行过排序。

    下面,让我们来看看冒泡排序的代码(从小打大)

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace BubbleSort
     7 {
     8     //冒泡排序算法:将n个记录看作按纵向排列,每趟排序时自下至上对每对相邻记录进行比较,
     9     //若次序不符合要求(逆序)就交换。
    10     //每趟排序结束时都能使排序范围内关键字最小的记录象一个气泡一样升到表上端的对应位置,
    11     //整个排序过程共进行n-1趟,依次将关键字最小、次小、第三小…的各个记录“冒到”表的第一个、
    12     //第二个、第三个…位置上。 
    13     class Program
    14     {
    15         static void Main(string[] args)
    16         {
    17             int[] array = new int[] { 38, 20, 46, 38, 74, 91, 12, 25 };
    18             BubbleSort(array);
    19             Console.ReadKey();
    20         }
    21         public static void BubbleSort(int[] ints)
    22         {
    23             int numberOfLoop = 0;
    24             bool flag = true;
    25             for (int i = 0; i < ints.Length - 1; i++)
    26             {
    27                 numberOfLoop++;//排序一次增加一次。
    28                 for (int j = 0; j < ints.Length - i - 1; j++)
    29                 {
    30                     //两个数作比较,把小的排在前边,最大的就会走到最后
    31                     if (ints[j] > ints[j + 1])
    32                     {
    33                         int temp = ints[j];
    34                         ints[j] = ints[j + 1];//交换两个变量的位置
    35                         ints[j + 1] = temp;
    36                         flag = false;
    37                     }
    38                 }
    39                 if (flag)
    40                 {
    41                     break;
    42                 }
    43             }
    44             DisplaySortResult(numberOfLoop, ints);//调用输出方法
    45         }
    46         private static void DisplaySortResult(int numberOfLoop, int[] array)
    47         {
    48             foreach (int i in array)
    49             {
    50                 Console.Write(i.ToString() + " ");
    51             }
    52             Console.WriteLine("\n循环次数:" + numberOfLoop.ToString());
    53         }
    54     }
    55 }

    3.选择排序:在算法中,选择排序是最不稳定的。

    选择排序的思想:

    每一趟从待排序的数据元素中选出最小(或最大)的一个元素, 顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。

    Eg:使用选择排序算法将下列数据从小到大的排列起来。

    38, 20, 46, 38, 74, 91, 12, 25

    让我们用code来解释:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace _3_SelectSort
     7 {
     8     //选择排序算法
     9     /*每一趟从待排序的数据元素中选出最小(或最大)的一个元素,
    10      * 顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。*/
    11     class Program
    12     {
    13         static void Main(string[] args)
    14         {
    15             int[] array = new int[] { 38, 20, 46, 38, 74, 91, 12, 25 };
    16             Selectort(array);
    17             Console.ReadKey();
    18         }
    19         static void Selectort(int[] ints)
    20         {
    21             int numberOfLoop = 0;
    22             int numberOfMin;//最小的元素
    23             //第一层循环--元素的位置
    24             for (int i = 0; i < ints.Length - 1; i++)
    25             {
    26                 numberOfMin = i;
    27                 //第二层循环:元素位置上的值
    28                 for (int j = i + 1; j < ints.Length; j++)
    29                 {
    30                     numberOfLoop++;
    31                     //获取最小元素
    32                     if (ints[numberOfMin] > ints[j])//ru
    33                     {
    34                         numberOfMin = j;
    35                     }
    36                 }
    37                 if (numberOfMin != i)
    38                 {
    39                     //交换变量的位置
    40                     int temp = ints[i];
    41                     ints[i] = ints[numberOfMin];
    42                     ints[numberOfMin] = temp;
    43                 }
    44             }
    45             //输出数据
    46             DisplaySortResult(numberOfLoop, ints);
    47         }
    48         private static void DisplaySortResult(int numberOfLoop, int[] array)
    49         {
    50             foreach (int i in array)
    51             {
    52                 Console.Write(i.ToString() + " ");
    53             }
    54             Console.WriteLine("\n循环次数:" + numberOfLoop.ToString());
    55         }
    56     }
    57 }

    4.插入排序算法: 假定这个数组的序是排好的,然后从头往后,如果有数比当前外层元素的值大,则将这个数的位置往后挪,直到当前外层元素的值大于或等于它前面的位置为止.这具算法在排完前k个数之后,可以保证a[1…k]是局部有序的,保证了插入过程的正确性.

    算法描述

      一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下: 

      ⒈ 从第一个元素开始,该元素可以认为已经被排序 

      ⒉ 取出下一个元素,在已经排序的元素序列中从后向前扫描 

      ⒊ 如果该元素(已排序)大于新元素,将该元素移到下一位置 

      ⒋ 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置 

      ⒌ 将新元素插入到下一位置中 

      ⒍ 重复步骤2 

      如果比较操作的代价比交换操作大的话,可以采用二分查找法来减少比较操作的数目。该算法可以认为是插入排序的一个变种,称为二分查找排序。

    让我来看看,插入排序算法是怎么样工作的:

    下面,我们用Code来说明:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace _4_InsertSort
     7 {
     8     //插入排序算法
     9     /*思想:
    10 1.从第一个元素开始,该元素可以认为已经被排序
    11 2.取出下一个元素,在已经排序的元素序列中从后向前扫描
    12 3.如果该元素(已排序)大于新元素,将该元素移到下一位置
    13 4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
    14 5.将新元素插入到该位置中
    15 6.重复步骤2~5*/
    16     class Program
    17     {
    18         static void Main(string[] args)
    19         {
    20             int[] array = new int[] { 12,15,9,20,6,31,24 };
    21             InsertSiort(array);
    22             Console.ReadKey();
    23         }
    24 
    25         public static void InsertSiort(int[] ints)
    26         {
    27             int numberOfLoop = 0;//循环累计器
    28             for (int i = 0; i < ints.Length - 1; i++)
    29             {
    30                 //处理第i个数。i之前的数字排列是有序的
    31                 int temp = ints[i];
    32                 int j;
    33                 //包含第i个数的前序列
    34                 for (j = i; j > 0; j--)
    35                 {
    36                     numberOfLoop++;
    37                     //比较第i个数与第j-1个数,如果第i个数小于第j-1个数,则i应该排在j-1的前边,将第j-1个数后移
    38                     //这样j-1的位置就是一个可以插入的位置,然后继续比较j-1前边的数,如果仍旧大于第i个数,则继续后移
    39                     //最后剩下一个位置,插入第i个数,这样包含i的前部分的序列就是有序的了。
    40                     if (ints[j - 1] > temp)
    41                     {
    42                         ints[j] = ints[j - 1];
    43                     }
    44                     else
    45                     {
    46                         break;
    47                     }
    48 
    49                 }
    50                 //最后一个位置设置成要排序数
    51                 ints[j] = temp;
    52             }
    53             DisplaySortResult(numberOfLoop, ints);
    54         }
    55         private static void DisplaySortResult(int numberOfLoop, int[] array)
    56         {
    57             foreach (int i in array)
    58             {
    59                 Console.Write(i.ToString() + " ");
    60             }
    61             Console.WriteLine("\n循环次数:" + numberOfLoop.ToString());
    62         }
    63     }
    64 }

     

  • 相关阅读:
    过滤器判断请求参数中是否含有某一字段
    vscode开发vue项目实现pc端自适应_cssrem_rem_reset.scss,pc端媒体查询常用设置
    element_ui的datePicker修改样式
    TCP/IP 卷一 APR、RAPR、ICMP
    TCP/IP 卷一:协议(IP层)
    常见负载均衡策略
    TCP/IP 卷一:协议(链路层)
    TCP/IP 卷一:协议(概述)
    RokcetMQ
    Zookeeper集群
  • 原文地址:https://www.cnblogs.com/acoll/p/2555999.html
Copyright © 2011-2022 走看看