算法(2)排序算法 1、插入排序
1.1 直接插入排序:
直接插入排序的基本思想:
1)将整个数组分为“已排序”和“未排序”的两部分,设已排序m,总长度n
2)从未排序部分选取第一个元素
3)遍历已排序的数组,查找需要插入的位置下标i
4)保护待排序数据,将下标大于i,小于m的所有元素右移一位
5)插入,进入下一轮循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 void InsertSort (type* arr, int num) { for (int m = 1 ; m < num; m++) { type tmp = arr[m]; int i = m - 1 ; for ( i = m - 1 ; i >= 0 &&arr[i]>tmp; i--) { arr[i + 1 ] = arr[i]; } arr[i+1 ] = tmp; } }
算法的性能分析:
时间复杂度:O(n^2)
(平均情况下向长度为m的序列中插入一个数据的平均移动速度是m/2,m从1累加到n-1)
空间复杂度:O(1)
稳定性:稳定
2、交换排序
2.1 快速排序
1)递归调用自身
2)每次将数组以“主元”为界分为较大组和较小组,再对两组分别进行快速排序
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 #include <algorithm> int Partition (int * arr, int num, int nLower, int nUpper) { int pivot = arr[nLower]; int nLeft = nLower + 1 ; int nRight = nUpper; while (true ) { while (nLeft <= nRight && arr[nLeft] <= pivot) nLeft++; while (nRight >= nLeft && arr[nRight] >= pivot) nRight--; if (nLeft > nRight) break ; if (nLeft < nRight) { std::swap (arr[nLeft], arr[nRight]); } } std::swap (arr[nLower], arr[nRight]); return nRight; } void QuickSort (int * arr, int num, int nLower = 0 , int nUpper = -1 ) { if (nUpper == -1 ) nUpper = num - 1 ; if (nLower < nUpper) { int nSplit = Partition (arr, num, nLower, nUpper); QuickSort (arr, num, nLower, nSplit - 1 ); QuickSort (arr, num, nSplit + 1 , nUpper); } }
算法性能分析:
快速排序在n较大时时间复杂度O(nlogn)
在n较小时或主元选择不合理时,时间复杂度为O(n^2)
空间复杂度O(logn)
快速排序是不稳定的
3、选择排序
3.1直接选择排序
1)数组被分为已排序与未排序两组
2)每次遍历未排序组找到最小的元素插入已排序组的最后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 template <typename type>void selectSort (type* items, int len) { for (int i = 1 ; i < len; i++) { int imin = i - 1 ; for (int j = i; j < len; j++) { if (items[j] < items[imin]) { imin = j; } } if (imin != i - 1 ) { type t = items[i - 1 ]; items[i - 1 ] = items[imin]; items[imin] = t; } } }