算法:排序算法

  1. 內部排序
    1. 插入排序
      1. 思想:將n個數組看成一個有序表和一個無序表,開始時有序表只有一個元素,排序過程是每次取出無序表中的第一個元素,將它的排序碼與有序表中元素的排序碼進行比較,將其放在合適的位置
        public static void insertSort(int[] array) {
            for (int i = 1;i<array.length;i++){
                int insertIndex=i-1;
                int insertVal=array[i];
                while (insertIndex>=0&&insertVal<=array[insertIndex]){
                    array[insertIndex+1]=array[insertIndex];
                    insertIndex--;
                }
                array[++insertIndex]=insertVal;
            }
        }

         

      2. 直接插入排序
      3. 希爾排序
    2. 選擇排序
      1. 思想:對於數組arr[n],從小到大:第一次從從arr[0]到arr[n-1]選一個最小值與arr[0]交行,第二次從arr[1]到arr[n-1]選一個最小值與arr[1]交換,以此類推,通過n-1次得到有序序列。從大到小排序,與從小到大的方式一樣,只是每次選出最大值
        public static void selectSort(int[] array) {
            for (int i = 0;i<array.length-1;i++){
                int min=array[i];
                int minIndex=i;
                for (int j = i+1;j<array.length;j++){
                    if(array[j]<min){
                        min=array[j];
                        minIndex=j;
                    }
                }
                if(minIndex!=i){
                    array[minIndex]=array[i];
                    array[i]=min;
                }
            }
        }
      2. 簡單選擇排序
      3. 堆排序
    3. 交換排序
      1. 冒泡排序
        1. 代碼
          public static void bubbleSort(int[] array) {
              //
              for(int i = 0;i<array.length;i++){
                  //
                  for(int j = 0;j<array.length-i-1;j++){
                      if(array[j]>array[j+1]){
                          int temp = array[j];
                          array[j]=array[j+1];
                          array[j+1]=temp;
                      }
                  }
              }
          }
        2. 優化:在每輪循環過程中,若有元素有交換,數列無序;若無元素交換,說明數列已然有序,直接跳出大循環
          public static void bubbleSort(int[] array) {
              //數組循環的輪數
              for (int i = 0;i<array.length;i++){
                  //有序標記,每輪初始值都是true
                  boolean flag = true;
                  for (int j = 0;j<array.length-i-1;j++){
                      if(array[j]>array[j+1]){
                          int temp = array[j];
                          array[j]=array[j+1];
                          array[j+1]=temp;
                          //若數組不是有序的將有序標記設置爲false
                          flag = false;
                      }
                  }
                  //有序標記爲true時,說明數組是有序的,跳槽循環
                  if(flag){
                      break;
                  }
              }
          }
        3. 優化:添加邊界,每輪循環後,邊界之後的元素肯定是有序的,無須比較,所以下輪循環時只需要比較邊界前的數列
          public static void bubbleSort(int[] array) {
              //最後一次交換的位置
              int lastExchangeIndex = 0;
              //邊界下標,邊界前面的爲無序數列,邊界後面的爲有序數列,每輪循環只需要比到此處
              int sortBorder=array.length-1;
              //數組循環的輪數
              for (int i = 0;i<array.length;i++){
                  //有序標記,每輪初始值都是true
                  boolean flag = true;
                  for (int j = 0;j<sortBorder;j++){
                      if(array[j]>array[j+1]){
                          int temp = array[j];
                          array[j]=array[j+1];
                          array[j+1]=temp;
                          //若數組不是有序的將有序標記設置爲false
                          flag = false;
                          //最後一次交換的位置
                          lastExchangeIndex = j;
                      }
                  }    
                  //有序標記爲true時,說明數組是有序的,跳槽循環
                  if(flag){
                      break;
                  }
                  //每輪循環後,將邊界設置爲最後交換的位置
                  sortBorder=lastExchangeIndex;
              }
          }
        4. 升級:雞尾酒排序
          public static void bubbleSort(int[] array) {
              //左邊界,邊界左邊爲有序數列
              int leftSortBorder=0;
              //右邊界,邊界右邊爲有序數列
              int rightSortBorder=array.length-1; 
              //向右比對時最後一次交換的位置
              int lastRightExchangeIndex =0;
              //向左比對時最後一次交換的位置
              int lastLeftExchangeIndex =0;
          
              for (int i = 0;i<array.length;i++){
                  boolean flag = true;
                  //從左往右,大的向後移動
                  for (int j = leftSortBorder;j<rightSortBorder;j++){
                          if(array[j]>array[j+1]){
                          int temp = array[j];
                          array[j]=array[j+1];
                          array[j+1]=temp;
                          lastRightExchangeIndex=j;
                          flag=false;
                  }
              }
              rightSortBorder=lastRightExchangeIndex;
              if(flag){
                  break;
              }
              //從右往左,小的向前移動
              flag = true;
              for (int j = rightSortBorder;j>leftSortBorder;j--){
                  if(array[j]<array[j-1]){
                      int temp = array[j];
                      array[j]=array[j-1];
                      array[j-1]=temp;
                      lastLeftExchangeIndex=j;
                      flag=false;
                  }
                }
                leftSortBorder=lastLeftExchangeIndex;
                if(flag){
                    break;
                }
              }
          }
      2. 快速排序
    4. 歸併排序
    5. 基數排序
      1. 介紹:
        1. 屬於分配式排序
        2. 效率高的穩定性排序
        3. 桶排序的擴展
        4. 以空間換時間,可能會出現OutOfMemoryError錯誤
      2. 思想:將數組中所有的數據統一爲同樣的數位長度,數位較短的數前面補零,然後從最低位開始比較,依次進行排序,直到最高位排序完成後,數列就是一個有序的數列
      3. 例子:數組{26,8,500},排序後{8,26,500}
      4. 代碼:
        public static void radixSort(int[] array) {
            //獲取最大元素的位數
            int max = array[0];
            int arrLength = array.length;
            for (int i =1;i<arrLength;i++){
                if(array[i]>max){
                    max=array[i];
                }
            }
            int maxLenght=(max+"").length();
        
            //二維數組表示10個桶,每個桶都是一個一位數組,存放array中的元素
            int[][] bucket = new int[10][arrLength];
            //桶中每次放入的數據個數
            int[] bucketElementCounts = new int[10];
                
            //排序
            for (int i =0,n=1;i<maxLenght;i++,n*=10){
                    
                //將元素放到桶中
                for (int j = 0;j<arrLength;j++){
                    //元素各位的值,各位、十位、百位...
                    int digitOfElement = array[j]/n % 10;
                    //將元素放到對應的桶中
                    bucket[digitOfElement][bucketElementCounts[digitOfElement]]=array[j];
                    bucketElementCounts[digitOfElement]++;
                }
        
               int index = 0;
               //遍歷桶
               for(int j = 0;j<10;j++){
                   //如果桶中有元素,遍歷桶,此處必須用bucketElementCounts[j]
                   if(bucketElementCounts[j]>0){
                       //依次將桶中的元素放到原數組中
                       for(int k = 0;k<bucketElementCounts[j];k++){
                           array[index++]=bucket[j][k];
                       }
                    }
                    //將桶中的元素的個數置爲0
                    bucketElementCounts[j]=0;
                }
            }
        
        }
  2. 外部排序
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章