1、插入排序(直接插入排序)
将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。
public static void insertSort(int[] a){
int temp=0;
for (int i = 1; i < a.length; i++) {
int j=i-1;
temp=a[i];
while(j>=0 && temp<a[j]){
a[j+1]=a[j];
j--;
}
a[j+1]=temp;
}
}
时间复杂度:O(n^2).
2、插入排序—希尔排序(Shell`s Sort)
对于大规模乱序数组插入排序很慢,因为他只会交换相邻的元素,因此元素只能一点一点地从数组的一端移动到另一端。希尔排序为了加速简单地改进了插入排序,交换不相邻的元素以对数组的局部进行排序。 先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。 就把原先的间隔1换成dk,dk逐渐变小直到变成1为止,这样做可以避免有些数很小在最末尾,要插入到头部挪位操作次数太多。
public static void shellSort(int[] a){
int dk=a.length/2;
while(dk>1){
shellInsertSort(a,dk);
dk=dk/2;
}
}
public static void shellInsertSort(int[] a,int dk) {
int temp=0;
for (int i = dk; i < a.length; i++) {
int j=i-dk;
temp=a[i];
while(j>=0 && temp<a[j]){
a[j+dk]=a[j];
j=j-dk;
}
a[j+dk]=temp;
}
}
3、选择排序
理解起来比较简单,每次遍历选择一个最小的放在前面
public static void selectSort(int[] a){
int temp;
for (int i=0;i<a.length;i++){
int min=i;
for (int j=i;j<a.length;j++) {
if (a[j]<a[min]){
min=j;
}
}
temp=a[min];
a[min]=a[i];
a[i]=temp;
}
}
4、选择排序中的堆排序
有点难理解
5、交换排序中的冒泡排序,时间复杂度:O(n^2).
public static void bubbleSort(int[] a){
int temp=0;
for(int i=a.length-1;i>0;i--){
for(int j=0;j<i;j++){
if(a[j]>a[j+1]){
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}
5.1 优化后的冒泡排序
插入flag,在排序好之后就及时退出循环
public static void bubbleSort(int[] a) {
int temp = 0;
boolean flag = true;
for (int i = a.length - 1; i > 0; i--) {
while (flag) {
flag=false;
for (int j = 0; j < i; j++) {
if (a[j] > a[j + 1]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
flag=true;
}
}
}
}
}
6、交换排序中的快速排序基本思想:
1)选择一个基准元素,通常选择第一个元素或者最后一个元素,
2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。
3)此时基准元素在其排好序后的正确位置
4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。
分析: 快速排序是通常被认为在同数量级(O(nlog2n))的排序方法中平均性能最好的。但若初始序列按关键码有序或基本有序时,快排序反而蜕化为冒泡排序。为改进之,通常以“三者取中法”来选取基准记录,即将排序区间的两个端点与中点三个记录关键码居中的调整为支点记录。快速排序是一个不稳定的排序方法。
重点
public static void quickSort(int[] a, int low, int high) {
if (low < high) {
int mid = getMiddle(a, low, high);
quickSort(a, low, mid - 1);
quickSort(a, mid + 1, high);
}
}
public static int getMiddle(int[] a, int low, int high) {
int key = a[low];
while (low < high) {
while (low<high && a[high] >=key) {
high--;
}
a[low] = a[high];
while ( low<high && a[low] <= key) {
low++;
}
a[high] = a[low];
}
a[low]=key;
return low;
}