一、插入排序
(一)简单插入排序:
插入排序是简单排序中最快的排序算法,虽然时间复杂度仍然为O(n*n),但是却比冒泡排序和选择排序快很多。
(1)原理:
假设前面的数列均为有序,逐一比较,如果比要插入的数大(从小到大排序)或小(从大到小排序),就互换位置。从将数列的第二个数设为要插入的数开始遍历数列。
(2)例子:
(3)代码:
public int[] kthLargestElement( int[] nums) {
int temp;
for(int i=1;i<nums.length;i++){
for(int j=0;j<i;j++){
if(nums[j]<nums[i]){
temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}
}
return nums;
}
(二)希尔排序
Shell排序旨在减少插入排序(即扫描列表并插入正确位置)所做的工作。可以证明,该方法将对时间复杂度为O(N1.25)的列表进行排序。
(1)原理:
1.将数的个数设为n,取奇数k=n/2,将下标差值为k的书分为一组,构成有序序列。
2.再取k=k/2 ,将下标差值为k的书分为一组,构成有序序列。
3.重复第二步,直到k=1执行简单插入排序。
(2)例子:
(3)代码:
二、快速排序:
顾名思义,QuickSort是实践中最快的已知排序算法(基于地址的排序可以更快)它的平均运行时间为O(n log n),速度非常快;但它具有O(n2)的最坏情况性能,但是这很难用很少的努力改变
****以下关于快排的内容全部来自于作者:清枫若待佳人醉 *****
来源:CSDN
原文:https://blog.csdn.net/qq_36528114/article/details/78667034
(一)左右指针法:
(1)原理:
1、选取一个关键字(key)作为枢轴,一般取整组记录的第一个数/最后一个,这里采用选取序列最后一个数为枢轴。
2、设置两个变量left = 0;right = N - 1;
3、从left一直向后走,直到找到一个大于key的值,right从后至前,直至找到一个小于key的值,然后交换这两个数。
4、重复第三步,一直往后找,直到left与right相遇,这时将key放置在left位置即可。
(2)例子:
(3)代码:
public int PartSort(int[] array,int left,int right)
{
int key = array[right];
while(left < right)
{
while(left < right && array[left] <= key)
{
++left;
}
while(left < right && array[right] >= key)
{
–right;
}
swap(array[left],array[right]);
}
swap(array[left],key);
return left;
}
(二)前后指针法
(1)原理:
1、定义变量cur指向序列的开头,定义变量pre指向cur的前一个位置。
2、当array[cur] < key时,cur和pre同时往后走,如果array[cur]>key,cur往后走,pre留在大于key的数值前一个位置。
3、当array[cur]再次 < key时,交换array[cur]和array[pre]。
通俗一点就是,在没找到大于key值前,pre永远紧跟cur,遇到大的两者之间机会拉开差距,中间差的肯定是连续的大于key的值,当再次遇到小于key的值时,交换两个下标对应的值就好了。
(2)例子:
(3)代码:
int PartSort(int array,int left,int right)
{
if(left < right){
int key = array[right];
int cur = left;
int pre = cur - 1;
while(cur < right)
{
while(array[cur] < key && ++pre != cur)//如果找到小于key的值,并且cur和pre之间有距离时则进行交换。注意两个条件的先后位置不能更换。
{
swap(array[cur],array[pre]);
}
++cur;
}
swap(array[++pre],array[right]);
return pre;
}
return -1;
}
(3)优势:
左右指针法和挖坑法只能针对顺序序列进行排序,如果是对一个链表进行排序, 就无用武之地了。