一、简单插入排序
插入排序将数组分为排序区和乱序区,排序过程中每次从乱序区中选择一个元素放入排序区,直到乱序区没有元素
| void insertion(vector<int>& nums) { int size = nums.size(); for (int i = 1; i < size; i++) { for (int j = i; j > 0 && (nums[j] < nums[j-1]); j--) { swap(nums, j, j - 1); } } }
|
二、优化
1. 融合二分查找
使用二分查找快速查找新元素在排序区的位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| void insert_sort( vector<int>& nums ) { int target; int k; for ( int i = 1; i < size; ++i ) { target = nums[i]; k = bin_search( nums, 0, i, target ); for ( int j = i-1; j >= k; --j ) { nums[j+1] = nums[j]; } nums[k] = target; } }
|
2. 加入哨兵位
在将新元素插入排序区使用哨兵位避免频繁交换元素的开销
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void insert_sort( vector<int>& nums ) { int size = nums.size(); int sentry; for ( int i = 1; i < size; ++i ) { sentry = nums[i]; for ( int j = i-1; j >= 0; j-- ) { if ( sentry < array[j] ) nums[j+1] = nums[j]; else break; } if ( j+1 != i ) nums[j+1] = sentry; } }
|
三、性能分析
- 时间复杂度:O(N2)
- 空间复杂度:O(1)
- 排序方式:原地
- 稳定性:稳定