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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容