首先讨论插入排序算法的思想:每趟将一个元素,按照其关键字值的大小插入到它前面已排序的子序列中,依次重复,直到插入全部元素。
1.直接插入排序算法:
1>第I趟,前面有I个元素是已经排序的。(1≤I<n)将ai插入到a0-ai-1这一序列的适当位置
2>重复执行n-1趟
代码实现:
public void StraightInsert(int[] nums){
for(int i = 1;i<nums.length;i++){
int temp = nums[i];
int j;
for(j = i - 1;j>=0&&temp<nums[j];j--){
nums[j+1] = nums[j];
}
nums[j+1] = temp;
}
}
复杂度分析:
若数组是排序好的,{1,2,3,4,5,6},比较n-1次,移动2(n-1)次,时间复杂度O(n)
最坏情况,{6,5,4,3,2,1}复杂度O(n2)
直接插入排序算法时间效率在O(n)到O(n2)之间,初始数组越有序,时间效率越高,temp占用一个存储单元,空间复杂度为O(1).
2.希尔排序(缩小增量排序)
由直接插入排序算法可以知道,数据序列越有序,时间效率越高。或者数组内元素数量越小,时间效率越高。希尔排序正是基于这个思想
希尔排序算法描述如下:
1>将一个数据序列分成若干组,每组由若干相隔一段距离(增量)的元素组成,在这个组内进行直接插入排序算法
2>增量初值通常设为数据序列长度的一半,以后每趟增量减半,最后值为1,随着增量减小,组数也减少,组内元素增加,数据序列接近有序。
public void ShellSort(int[] nums){
int len = nums.length;
for(int delta = len/2;delta>0;delta = delta/2){
for(int i = delta;i<nums.length;i++){
int temp = nums[i];
int j;
for(j = i - delta;j>=0&&temp<nums[j];j = j-delta){
nums[j+delta] = nums[j];
}
nums[j+delta] = temp;
}
}
}
3.冒泡排序
比较相邻两个元素大小,如果反序,交换。每进行一趟,都会将数据序列中最大元素交换到最后位置。
public void bubbleSort(int[] nums){
int len = nums.length;
for(int i = 0;i<len-1;i++){
for(int j = 0;j<len-1-i;j++){
if(nums[j]>nums[j+1]){
int temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
}
每一趟挑出未排序序列中的最大值放到未排序序列的最后一位。
时间复杂度分析:如果原数组就是从小到大,则只需要扫描1次,时间复杂度O(n)。最坏情况扫描n-1次,比较移动次数都是O(n2)。所以冒泡排序时间复杂度在线性和平方之间,初始序列越有序,效率越高。空间复杂度为O(1).
4.快速排序
1>设两个指针I和j,初值分别为0和nums.length-1。并设枢轴元素nums[0]赋给pivot
2>j从右往左扫描,如果元素大于pivot,则j--。直到出现小于pivot的元素nums[j],将a[j]值赋给nums[I]。此时nums[j]相当于空单元,并执行I++一次。
3>I从左到右扫描,如果元素小于pivot,则I++。直到出现大于pivot的元素nums[I],将nums[I]赋给nums[j]。此时nums[I]相当于空单元,并执行j--一次。
4>重复执行2和3,直到I>=j。此时nums[I]是空单元,将pivot赋给nums[I]。
5>上述四步的方法会return出一个I值。在i左侧,都是小于nums[I]的,在i右侧,都是大于nums[I]的。对左右两部分子序列进行递归操作。直至全部排序完毕
public int Partition(int[] nums,int low,int high){
int pivot = nums[low];
while(low<high){
while(low<high && nums[high]>=pivot){
high--;
}
if(low<high){
nums[low] = nums[high];
low++;
}
while(low<high && nums[low]<=pivot){
low++;
}
if(low<high){
nums[high] = nums[low];
}
}
nums[low] = pivot;
return low;
}
public void QuickSort(int[] nums,int low,int high){
int pivotkey;
if(low<high){
pivotkey = Partition(nums, low, high);
QuickSort(nums,low,pivotkey-1);
QuickSort(nums,pivotkey+1,high);
}
}