c#七种常用排序算法

一、常见排序算法一览:

时间复杂度:  是一个函数,它定量描述了该算法的运行时间。

空间复杂度:一个算法在运行过程中临时占用存储空间大小的量度。

稳定性:保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同就稳定,反之不稳定。

视觉直观感受 7 种常用的排序算法

二、算法C#实现:

1、直接插入排序

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespace csharpconsole{    class Program    {/*

具体算法描述如下:

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

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

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

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

5.将新元素插入到该位置后

6.重复步骤2~5

*/publicstaticvoidInsertSort(int[] List)        {inttmp =0;intlen = List.Length;inti =0;intj =0;for(i =1; i < len; i++)            {                tmp = List[i];for(j = i -1; j >=0; j--)                {if(tmp < List[j])                    {                        List[j +1] = List[j];                    }elseif(tmp > List[j])                    {break;                    }                }                List[j +1] = tmp;            }return;        }staticvoidMain(string[] args)        {int[] intArr = {10,2,56,12,6,78,34,23,9,18,7};            InsertSort(intArr);for(intk =0; k < intArr.Length; k++)            Console.WriteLine(intArr[k]);            Console.ReadKey();        }    }}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

2、希尔排序

实际上是分组的插入排序。缩小增量排序。先取定一个小于n的整数d1作为第一个增量,把表的全部记录分成d1个组,所有距离为d1的倍数的记录放在同一个组中,在各组内进行直接插入排序;然后,取第二个增量d2(<d1),重复上述的分组和排序,直至所取的增量dt=1。

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespace csharpconsole{    class Program    {publicstaticvoidShellSort(int[] List)        {inttmp =0;intlen = List.Length;inti =0;intj =0;intd = len /2;/* 初始步长取数组长度的一半 *//* 观察看如果d=1的话,即是普通的插入排序算法 */while(d >=1)            {/* 把距离为 d 的元素编为一个组,扫描所有组 */for(i = d; i < len; i++)                {                    tmp = List[i];for(j = i - d; j >=0; j = j - d)                    {if(tmp < List[j])                        {                            List[j + d] = List[j];                        }elseif(tmp > List[j])                        {break;                        }                    }                    List[j + d] = tmp;                }                d = d /2;            }return;        }staticvoidMain(string[] args)        {int[] intArr = {10,2,56,12,6,78,34,23,9,18,7};            ShellSort(intArr);for(intk =0; k < intArr.Length; k++)            Console.WriteLine(intArr[k]);            Console.ReadKey();        }    }}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

3、冒泡排序(交换排序)

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespacecsharpconsole{classProgram{publicstaticvoidBubbleSort(int[] List)        {inti =0;intj =0;intlen = List.Length;intswap =0;/*

第一趟排序:通过两两比较,找到第一小的数值 1 ,将其放在序列的第一位。

第二趟排序:通过两两比较,找到第二小的数值 2 ,将其放在序列的第二位。

第三趟排序:通过两两比较,找到第三小的数值 3 ,将其放在序列的第三位。

至此,所有元素已经有序,排序结束。

*/for(i = len -1; i >=0; i--)            {for(j = len -1; j >= len - i; j--)                {                    if (List[j] < List[j -1])                    {                        swap = List[j];                        List[j] = List[j -1];                        List[j -1] = swap;                    }                }            }return;        }staticvoidMain(string[] args)        {int[] intArr = {10,2,56,12,6,78,34,23,9,18,7};            BubbleSort(intArr);for(intk =0; k < intArr.Length; k++)            Console.WriteLine(intArr[k]);            Console.ReadKey();        }    }}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

4、快速排序(交换排序)

步骤:

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespacecsharpconsole{classProgram{publicstaticvoidQuickSort(int[] List,intleft,intright)        {intbaseNum =0;intlow =0;inthigh =0;            if (left < right)            {                baseNum = List[left];                low = left;                high = right;while(low < high)                {/* 从右往左扫描 */while((high > low) && (baseNum < List[high]))                    {                        high--;                    }                    List[low] = List[high];/* 从左往右扫描 */while((low < high) && (baseNum > List[high]))                    {                        low++;                    }                    List[high] = List[low];                }                List[low] = baseNum;                QuickSort(List, left, low -1);                QuickSort(List, low +1, right);            }return;        }staticvoidMain(string[] args)        {int[] intArr = {10,2,56,12,6,78,34,23,9,18,7};            QuickSort(intArr,0, intArr.Length -1);for(intk =0; k < intArr.Length; k++)            Console.WriteLine(intArr[k]);            Console.ReadKey();        }    }}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

5、简单选择排序(直接选择排序):

(1) 从待排序序列中,找到关键字最小的元素;

(2) 如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换;

(3) 从余下的 N - 1 个元素中,找出关键字最小的元素,重复(1)、(2)步,直到排序结束。

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace csharpconsole{classProgram{publicstaticvoidSelectionSort(int[] List)        {intindex=0;intswap =0;intlen = List.Length;inti =0;intj =0;for(; i < len; i++)            {/* 找到这一趟循环最小的值,记录下标,默认下标为i */index= i;for(j = i +1; j < len; j++)                {if(List[j] < List[index])                    {index= j;                    }                }/* 如果下标有改变,就交换数值 */if(index!= i)                {                    swap = List[i];                    List[i] = List[index];                    List[index] = swap;                }            }return;        }staticvoidMain(string[] args)        {int[] intArr = {10,2,56,12,6,78,34,23,9,18,7};            SelectionSort(intArr);for(intk =0; k < intArr.Length; k++)            Console.WriteLine(intArr[k]);            Console.ReadKey();        }    }}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

6、堆排序

步骤:

(1)根据初始数组去构造初始堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大)。

(2)每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆。

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespacecsharpconsole{classProgram    {publicstaticvoidHeapAdjust(int[]array,intparent,intlength)        {inttemp =array[parent];// temp保存当前父节点intchild =2* parent +1;// 先获得左孩子while(child < length)            {// 如果有右孩子结点,并且右孩子结点的值大于左孩子结点,则选取右孩子结点if(child +1< length &&array[child] =array[child])                {break;                }// 把孩子结点的值赋给父结点array[parent] =array[child];// 选取孩子结点的左孩子结点,继续向下筛选parent = child;                child =2* child +1;            }array[parent] = temp;        }publicstaticvoidHeapSort(int[]list)        {// 循环建立初始堆for(inti =list.Length /2; i >=0; i--)            {                HeapAdjust(list, i,list.Length -1);            }// 进行n-1次循环,完成排序for(inti =list.Length -1; i >0; i--)            {// 最后一个元素和第一元素进行交换inttemp =list[i];list[i] =list[0];list[0] = temp;// 筛选 R[0] 结点,得到i-1个结点的堆HeapAdjust(list,0, i);            }        }staticvoidMain(string[] args)        {int[] intArr = {10,2,56,12,6,78,34,23,9,18,7};            HeapSort(intArr);for(intk =0; k < intArr.Length; k++)            Console.WriteLine(intArr[k]);            Console.ReadKey();        }    }}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

7、归并排序

步骤:

(1)“分解”——将序列每次折半划分。

(2)“合并”——将划分后的序列段两两合并后排序。

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;namespacecsharpconsole{classProgram    {publicstaticvoidMerge(int[]array,intlow,intmid,inthigh)        {inti = low;// i是第一段序列的下标intj = mid +1;// j是第二段序列的下标intk =0;// k是临时存放合并序列的下标int[] array2 =newint[high - low +1];// array2是临时合并序列// 扫描第一段和第二段序列,直到有一个扫描结束while(i <= mid && j <= high)            {// 判断第一段和第二段取出的数哪个更小,将其存入合并序列,并继续向下扫描if(array[i] <=array[j])                {                    array2[k] =array[i];                    i++;                    k++;                }else{                    array2[k] =array[j];                    j++;                    k++;                }            }// 若第一段序列还没扫描完,将其全部复制到合并序列while(i <= mid)            {                array2[k] =array[i];                i++;                k++;            }// 若第二段序列还没扫描完,将其全部复制到合并序列while(j <= high)            {                array2[k] =array[j];                j++;                k++;            }// 将合并序列复制到原始序列中for(k =0, i = low; i <= high; i++, k++)            {array[i] = array2[k];            }        }publicstaticvoidMergePass(int[]array,intgap,intlength)        {inti =0;// 归并gap长度的两个相邻子表for(i =0; i +2* gap -1< length; i = i +2* gap)            {                Merge(array, i, i + gap -1, i +2* gap -1);            }// 余下两个子表,后者长度小于gapif(i + gap -1< length)            {                Merge(array, i, i + gap -1, length -1);            }        }publicstaticint[] MergeSort(int[]list)        {for(intgap =1; gap

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

0

0

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容