掌握常见的内部排序方法(插入排序,冒泡排序,选择排序,快速排序,堆排序,希尔排序,归并排序,基数排序等)

掌握常见的内部排序方法(插入排序,冒泡排序,选择排序,快速排序,堆排序,希尔排序,归并排序,基数排序等)。
数组高级以及Arrays(掌握)
排序方法
空间复杂度
时间复杂度
稳定性
 
 
直接插入排序
O1
平均On2
最坏On2
最好On
 
稳定
 折半插入排序
 
O1
平均Onlogn
最坏On2
 
稳定
希尔排序
O1
平均On2
不稳定
 
           冒泡排序
 
O1
平均On2
最坏On2
最好On
 
稳定
           快速排序
平均Onlogn
最坏On
平均Onlogn
最坏On2
平均Onlogn
 
不稳定
 
           简单选择排序
 
O1
始终On2
 
不稳定
           堆排序
 
O1
平均Onlogn
建堆On
调整Ologn
 
不稳定
 
归并排序
On
Onlogn
稳定
 
基数排序
Od(n+r)
Od(n+r)
稳定
(1)排序
  A:冒泡排序
     相邻元素两两比较,大的往后放,第一次完毕,最大值出现在了最大索引处。同理,其他的元素就可以排好。
          
       public static void bubbleSort(int[] arr) {
         for(int x=0; x<arr.length-1; x++) {
           for(int y=0; y<arr.length-1-x; y++) {
              if(arr[y] > arr[y+1]) {
               int temp = arr[y];
                arr[y] = arr[y+1];
               arr[y+1] = temp;
                   }
                }
              }
           }         
  B:选择排序
           把0索引的元素,和索引1以后的元素都进行比较,第一次完毕,最小值出现在了0索引。同理,其他的元素就可以排好。
          
       public static void selectSort(int[] arr) {
           for(int x=0; x<arr.length-1; x++) {
             for(int y=x+1; y<arr.length; y++) {
                  if(arr[y] < arr[x]) {
                    int temp = arr[x];
                    arr[x] = arr[y];
                    arr[y] = temp;
                     }
                 }
              }
           }
C.插入排序算法:
 public static void insertSort(int[] arr) {
      for (int i = 1; i < arr.length; i++) {
          if(arr[i]<arr[i-1]){
           arr[0]=arr[i];
          for(int j=i-1;arr[0]<arr[j];j--)//只要arr[i]大的都后移,找到arr[i]合适的插入位置
           arr[j+1]=arr[j];
        arr[j+1]=arr[0];
            }
        }
    }
D希尔排序:
/*
* 希尔排序:先取一个小于n的整数d1作为第一个增量,
* 把文件的全部记录分成(n除以d1)个组。所有距离为d1的倍数的记录放在同一个组中。
* 先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,
* 直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
*/
public class ShellSort {
public static void sort(int[] data) {
for (int i = data.length / 2; i > 2; i /= 2) {//设置增量
for (int j = 0; j < i; j++) {
insertSort(data, j, i);
}
}
insertSort(data, 0, 1);
}
private static void insertSort(int[] data, int start, int inc) {
for (int i = start + inc; i < data.length; i += inc) {
for (int j = i; (j >= inc) && (data[j] < data[j - inc]); j -= inc){
SortTest.swap(data, j, j - inc);
}
}
}
}
E.快速排序:
 Void Quicksort(int A[],int low,int high){
  If(low<high){
      Int pivotpos= partion(A, low ,high);//获取枢轴数位置
      Quicksort(A,  low,pivotpos-1);
Quicksort(A,pivotpos-1,high)
}
}
Int partion(int A[],int low ,int high){
   Int pivot=Alow];
  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;
   }
}
F:归并排序:
public static int[] sort(int[] a,int low,int high){
        int mid = (low+high)/2;
        if(low<high){
            sort(a,low,mid);//分成两个子序列,分别递归排序
            sort(a,mid+1,high);
            //左右归并
            merge(a,low,mid,high);
        }
        return a;
    }
//将两个有序表合并成一个有序表
   public static void merge(int[] a, int low, int mid, int high) {
        int[] temp = new int[high-low+1];//定义一个数组
        int i= low;
        int j = mid+1;
        int k=0;
        // 把较小的数先移到新数组中
        while(i<=mid && j<=high){
            if(a[i]<a[j]){
               temp[k++] = a[i++];
            }else{
               temp[k++] = a[j++];
            }
        }
        // 把左边剩余的数移入数组 
        while(i<=mid){
            temp[k++] = a[i++];
        }
        // 把右边边剩余的数移入数组
        while(j<=high){
            temp[k++] = a[j++];
        }
        // 把新数组中的数覆盖nums数组
        for(int x=0;x<temp.length;x++){
          a[x+low] = temp[x];//原数组从low开始的
        }
    } 
G:堆排序
 //构建大根堆:将array看成完全二叉树的顺序存储结构
    private int[] buildMaxHeap(int[] array){
//从最后一个节点array.length-1的父节点(array.length-1/2开始,直到根节点0,反复调整堆
         for(int i=(array.length-1)/2;i>=0;i--){
              adjustDownToUp(array, i,array.length);
          }
          return array;
      }
     
//将元素array[k]自下往上逐步调整树形结构
     private void adjustDownToUp(int[] array,int k,int length){
         int temp = array[k];  
         for(int i=2*k; i<length; i=2*i){    //i为初始化为节点k的左孩子,沿节点较大的子节点向下调整
             if(i<length && array[i]<array[i+1]){  //取节点较大的子节点的下标
                 i++;   //如果节点的右孩子>左孩子,则取右孩子节点的下标
            }
             if(temp>=array[i]){  //根节点 >=左右子女中关键字较大者,调整结束
                 break;
             }else{   //根节点 <左右子女中关键字较大者
                 array[k] = array[i];  //将左右子结点中较大值array[i]调整到双亲节点上
                k = i; //【关键】修改k值,以便继续向下调整
             }
         }
        array[k] = temp;  //被调整的结点的值放人最终位置
    }   
//堆排序
      public int[] heapSort(int[] array){
          array = buildMaxHeap(array); //初始建堆,array[0]为第一趟值最大的元素
          for(int i=array.length-1;i>1;i--){ 
             int temp = array[0];  //将堆顶元素和堆低元素交换,即得到当前最大元素正确的排序位置
              array[0] = array[i];
             array[i] = temp;
            adjustDownToUp(array, 0,i-1);  //整理,将剩余的元素整理成堆
         }
         return array;
    }
(2)查找
      A:基本查找
           针对数组无序的情况
          
           public static int getIndex(int[] arr,int value) {
              int index = -1;
             
              for(int x=0; x<arr.length; x++) {
                  if(arr[x] == value) {
                     index = x;
                     break;
                  }
              }
             
              return index;
           }
       B:二分查找(折半查找)
           针对数组有序的情况(千万不要先排序,在查找)
          
           public static int binarySearch(int[] arr,int value) {
              int min = 0;
              int max = arr.length-1;
              int mid = (min+max)/2;
             
              while(arr[mid] != value) {
                  if(arr[mid] > value) {
                     max = mid - 1;
                  }else if(arr[mid] < value) {
                     min = mid + 1;
                  }         
                  if(min > max) {
                     return -1;
                  }   
                  mid = (min+max)/2;
              }           
              return mid;
           } 
posted @ 2019-05-31 11:44  励志前行  阅读(1572)  评论(0编辑  收藏  举报