C#算法

递归

任何一个方法既可以调用其他方法又可以调用自己,而当这个方法调用自己时,我们就叫它递归函数或者递归方法!

通常递归有两个特点:    

1.递归方法一直会调用自己直到某些条件满足,也就是说一定要有出口;

2.递归方法会有一些参数,而它会把这些新的参数值传递给自己;(自己调自己);

冒泡排序

通过相邻两个值的大小比较(多次),保证数值排序为从小到大的排序方法。

    效果及实现原理:外层的数列个数次的循环,每次循环会将最大的数值“冒泡”到右端,因为是相邻的两两比较。

    具体实现:双重循环,外层数列个数次,保证每一个数值都处于正确位置(因为每循环一次,至少会确定一个数值的正确位置),内层从数列个数次逐渐减少次数,因为每一次外层循环会确定最大值、倒数第二大值……我们在下一次循环就可以忽略掉他们。

插入排序

插入排序(Insert Sort):本质上是待排序列里的元素一个一个的与已排列好的元素进行比较,将其插入到已排列好的序列中,直到没有待排列的元素。类似于打牌的时候摸牌的动作:手上的牌是排列好的,桌子上的牌是待排序的,每从桌子上抓到一只牌,按照一定次序将其插入到手中

int i = 0, j = 0;
int key;
for (j = 1; j < array.Length; j++)
{
  key = array[j];
  i = j - 1;
  while (i >= 0 && array[i] > key)
  {
    array[i + 1] = array[i];
    i -= 1;
  }
  array[i + 1] = key;
  Console.Write("Step {0}:", j);
  DisplayArrayToConsole(array);
}

快速排序

快速排序(Quicksort)是对冒泡排序的一种改进。
(在数据量小于20的时候,插入排序具有最好的性能。当大于20时,快速排序具有最好的性能,归并(merge sort)和堆排序(heap sort)也望尘莫及,尽管复杂度都为nlog2(n)。)
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
由此思想,我们可以实现快速排序的代码:
注意基准数据永远不变,永远是和基准数据进行比较,无论在什么位置,最后的目的就是把基准数据放在中间,小的放前面大的放后面。

namespace QuickSort
{
class QuickSort
{
private int Func(int[] n, int left, int right)
{
  int baseNum = n[left]; // 基准数据

  int i = left;
  int j = right;
  while (true)
  {
    if (n[i] < baseNum && i < j)
    {
      i++;
    }
    else if (n[i] > baseNum && i < j)
    {
      int number = n[i];
      n[i] = n[j];
      n[j] = number;
      j--;
    }
    else if (n[j] < baseNum && i < j)
    {
      int number = n[i];
      n[i] = n[j];
      n[j] = number;
      i++;
    }
    else if (n[j] > baseNum && i < j)
    {
      j--;
    }
    else if (i == j)
    {
      n[i] = baseNum;
      break;
    }
  }
  return i;
}

public void QuickSortFunc(int[] n, int left, int right)
{
  //左下标一定小于右下标,否则就超越了
  if (left < right)
  {
    //对数组进行分割,取出下次分割的基准标号
    int i = Func(n, left, right);

    //对“基准标号“左侧的一组数值进行递归的切割,以至于将这些数值完整的排序
    QuickSortFunc(n, left, i - 1);

    //对“基准标号“右侧的一组数值进行递归的切割,以至于将这些数值完整的排序
    QuickSortFunc(n, i + 1, right);

  }
}
static void Main(string[] args)
{
  int[] n = { 23, 45, 60, 10, 17, 101,12};
  QuickSort qs = new QuickSort();
  qs.QuickSortFunc(n, 0, n.Length - 1);
  for (int i = 0; i < n.Length; i++)
  {  
    Console.WriteLine(n[i]);
  }

  Console.ReadLine();
}
}
}

归并排序

 归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

而它的时间复杂度就是N*logN,此算法采用的是二分法,所以可以认为对应的对数函数底数为2,也有可能是三分法,底数为3,以此类推。

每次合并操作的平均时间复杂度为O(n),而完全二叉树的深度为|log2n|。总的平均时间复杂度为O(nlogn)。而且,归并排序的最好,最坏,平均时间复杂度均为O(nlogn)。

外排序

Bit-map空间压缩和快速排序去重

1. Bit-map的基本思想
  32位机器上,对于一个整型数,比如int a=1 在内存中占32bit位,这是为了方便计算机的运算。但是对于某些应用场景而言,这属于一种巨大的浪费,因为我们可以用对应的32bit位对应存储十进制的0-31个数,而这就是Bit-map的基本思想。Bit-map算法利用这种思想处理大量数据的排序、查询以及去重。
  Bitmap在用户群做交集和并集运算的时候也有极大的便利。

原文地址:https://www.cnblogs.com/fantaohaoyou/p/9401634.html