交换,就是根据序列中两个元素关键字的比较结果来对换这两个记录在序列中的位置。,基于交换的排序
算法有很多。以冒泡排序和快速排序举例。
冒泡排序:
public static int[] bubbleSort(int[] array)
{
int[] newArray = Arrays.copyOf(array, array.length);
for (int i = 0; i < newArray.length-1; i++) // 比较的趟数
{
for (int j=0; j< newArray.length-1-i; j++) // 每一次两两比较的次数
{
if (newArray[j] > newArray[j+1])
{
int tmp = newArray[j];
newArray[j] = newArray[j+1];
newArray[j+1] = tmp;
}
}
}
return newArray;
}
稳定性:冒泡排序是一个稳定的排序方法。冒泡排序中所产生的有序子序列一定是全局有序的。
快速排序:(基于分治法)
public void quick(int[] a)
{
if (a.length > 0)
{
quickSort(a, 0, a.length-1);
}
}
public void quickSort(int[] a, int low, int high)
{
if (low < high) // 递归跳出的条件
{
int pivotpos = Partition(a, low, high);
// 依次对两个子表进行递归排序
quickSort(a, 0, pivotpos -1);
quickSort(a, pivotpos +1, high);
}
}
// 划分操作,将表A[low..high]划分为满足上述条件的两个子表
private int Partition(int[] a, int low, int high)
{
int pivot = a[low]; // 将当前表中第一个元素设为枢轴值,对表进行划分
while (low < high) // 循环跳出条件
{
while (low < high && a[high] >= pivot)
{
high--;
}
a[low] = a[high];
while (low < high && a[low] <= pivot)
{
low++;
}
a[high] = a[low];
}
// 枢轴元素放到最终位置上
a[low] = pivot; // 将基准元素放入到正确的位置上(原数组分为三段 左边 基准点 右边)
return low;
}
空间效率:空间复杂度最坏为O(n),平均情况下为O(log2n)。
时间效率:最坏情况下时间复杂度为O(n2),平均为O(nlog2n)。
稳定性:快速排序是不稳定的排序算法。
快速排序是所有内部排序算法中平均性能最优的排序算法。
如何提高快速排序算法的效率? 2种方法
(1)当递归过程中得到的子序列的规模较小时,不要再继续递归调用快速排序,可以直接采用直接插入排序算法
进行后续的排序工作。
(2)尽量选一个可以将数据中分的枢轴元素。如从序列的头尾以及中间选取三个元素,再去这三个元素的中间
值作为最终的枢轴元素;或者随机从当前表中选取枢轴元素,这样做使得最坏情况在实际排序中几乎不会发生。