1.直接插入排序
【思想】利用有序表的插入操作进行排序
有序表的插入:将一个记录插入到已排好序的有序表中,从而得到一个新的有序表
【特点】稳定
空间代价:O(1) 时间代价:O(n^2)
1 void InsertSort (int Array[], int n) 2 { 3 //Array[]为待排序数组,n为数组长度 4 int TempRecord; // 临时变量 5 for (int i = 1; i < n; i ++) // 依次插入第i个记录 6 { 7 TempRecord = Array[i]; 8 //从i开始往前寻找记录i的正确位置 9 int j = i - 1; 10 //将那些大于等于记录i的记录后移 11 while ((j >= 0) && (TempRecord < Array[j])) 12 { 13 Array[j+1] = Array[j]; 14 j --; 15 } 16 //此时j后面就是记录i的正确位置,回填 17 Array[j + 1] = TempRecord; 18 } 19 }
2.折半插入排序
【思想】
·在插入第i个记录时,前面的记录已经是有序的了
·可以用二分法查找第i个记录的正确位置
由于直接插入排序算法利用了有序表的插入操作,故将顺序查找替换为二分法查找即可
【特点】稳定
空间代价:O(1) 时间代价:O(n^2)
1 void BinaryInsertSort(int R[],int n) 2 { 3 for(int i = 1; i < n; i ++) //共进行n-1次插入 4 { 5 int left = 0,right = i - 1; 6 int temp = R[i]; 7 while(left <= right) 8 { 9 int middle = left + (right - left)/2; //取中点 10 if(temp < R[middle]) //取左区间 11 right = middle - 1; 12 else //取右区间 13 left = middle + 1; 14 } 15 //此时left处应为要插入的位置 16 for(int j = i - 1; j >= left; j --) 17 R[j + 1] = R[j]; //元素后移空出插入位 18 R[left] = temp; 19 } 20 }
3.希尔排序
【思想】
·先将序列转化为若干小序列,在这些小序列内进行插入排序
·逐渐扩大小序列的规模,而减少小序列的个数,使得待排序序列逐渐处于更有序的状态
·最后对整个序列进行扫尾直接插入排序,从而完成排序
【特点】不稳定
空间代价:O(1) 时间代价:在O(logn)~O(n^2)之间,大致O(n^1.3)
1 template <class T > 2 void ShellSort (T Vector[], int arrSize) 3 { 4 T temp; 5 int gap = arrSize / 2; //gap是子序列间隔 6 while (gap != 0) //循环,直到gap为零 7 { 8 for (int i = gap; i < arrSize; i ++) 9 { 10 temp = Vector[i];//直接插入排序 11 int j = i; 12 for ( ; j >= gap; j -= gap) 13 { 14 if (temp < Vector[j-gap]) 15 Vector[j] = Vector[j-gap]; 16 else break; 17 } 18 Vector[j] = temp; 19 } 20 gap = gap / 2;//步长每次缩短为原来的一半 21 } 22 }