数据结构-排序&查找

文章对比了不同排序算法如冒泡、选择、插入、希尔、快速、归并、基数和堆排序的运行时间,并提供了二分查找和插值查找的实现。快速排序和堆排序在时间效率上表现最优。
摘要由CSDN通过智能技术生成

冒泡排序

 public class BubbleSort {
     public static void main(String[] args) {
         int[] temp = new int[80000];
         for (int i = 0; i < 80000; i++) {
             temp[i] = (int) (Math.random() * 8000000);
         }
         long date1 = System.currentTimeMillis();
         Arrays.toString(bubbleSort(temp));
         long date2 = System.currentTimeMillis();
         System.out.println("冒泡排序的运行时间为" + (date2  - date1) + "ms");
     }
 ​
     //冒泡排序
     public static int[] bubbleSort(int[] arr){
         int temp = 0;
         boolean flag = false;
         for (int i = 0; i < arr.length - 1; i++) {
             for (int j = 0; j < arr.length - 1 - i; j++) {
                 if (arr[j] > arr[j + 1]){
                     flag = true;
                     temp = arr[j];
                     arr[j] = arr[j +1];
                     arr[j + 1] = temp;
                 }
             }
             if (!flag){
                 break;
             }else {
                 flag = false;
             }
         }
         return arr;
     }
 }

选择排序

 public static int[] selectSort(int[] arr){
         for (int i = 0; i < arr.length; i++) {
             int minIndex = i;
             int min = arr[i];
             for (int j = i + 1; j < arr.length; j++) {
                 if (min > arr[j]){
                     min = arr[j];
                     minIndex = j;
                 }
             }
             if (minIndex != i){
                 arr[minIndex] = arr[i];
                 arr[i] = min;
             }
         }
 ​
         return arr;
     }

插入排序

 public static int[] insertSort(int[] arr){
         for (int i = 1; i < arr.length; i++) {
             int temp =arr[i];
             int insertIndex = i - 1;
 ​
             while (insertIndex >= 0 && temp < arr[insertIndex]){
                 arr[insertIndex + 1] = arr[insertIndex];
                 insertIndex--;
             }
             if (insertIndex + 1 != i){
                 arr[insertIndex + 1] = temp;
             }
         }
         return arr;
     }

希尔排序

 public static int[] shellSort(int[] arr){
         int temp = 0;
         for (int gap = arr.length / 2; gap > 0; gap /= 2) {
             for (int i = gap; i < arr.length ; i++) {
                 for (int j = i - gap; j >= 0 ; j -= gap) {
                     if (arr[j] > arr[j + gap]){
                         temp = arr[j];
                         arr[j] = arr[j + gap];
                         arr[j + gap] = temp;
                     }
                 }
             }
         }
         return arr;
     }

快速排序

 //快速排序
     public static int[] quickSort(int[] arr, int left, int right){
         int l = left;
         int r = right;
         int mid = arr[(left + right) / 2];
         int temp = 0;
         while (l < r){
             //在mid的左边一直找,找到大于等于mid值才退出
             while (arr[l] < mid){
                 l += 1;
             }
             //在mid的右边一直找,找到小于等于mid值才退出
             while (arr[r] > mid){
                 r -= 1;
             }
             if (l >= r){
                 break;
             }
             //交换
             temp = arr[l];
             arr[l] = arr[r];
             arr[r] = temp;
 ​
             //如果arr[l]==mid 前移一位
             if (arr[l] == mid){
                 r -= 1;
             }
             //如果arr[r]==mid 后移一位
             if (arr[r] == mid){
                 l += 1;
             }
         }
         if (l == r){
             l += 1;
             r -= 1;
         }
         if (left < r){
             quickSort(arr, left, r);
         }
         if (right > l){
             quickSort(arr, l, right);
         }
         return arr;
     }

归并排序

 //归并排序
     public static int[] merge(int[] arr, int left, int mid, int right, int[] temp){
         int i = left; //初始i,左边有序序列的初始索引
         int j = mid + 1; //初始j,右边有序序列的初始索引
         int t = 0; //指向temp数组的当前索引
 ​
         //把左右两边的数据按照规则填充到temp数组
         while (i <= mid && j <= right){
             if (arr[i] <= arr[j]){
                 temp[t] = arr[i];
                 t += 1;
                 i += 1;
             }else {
                 temp[t] = arr[j];
                 t += 1;
                 j += 1;
             }
         }
         while (i <= mid){
             temp[t] = arr[i];
             t += 1;
             i += 1;
         }
         while (j <= right){
             temp[t] = arr[j];
             t += 1;
             j += 1;
         }
 ​
         t = 0;
         int tempLeft = left;
         while (tempLeft <= right){
             arr[tempLeft] = temp[t];
             t += 1;
             tempLeft += 1;
         }
         return arr;
     }
 ​
     public static int[] mergeSort(int[] arr, int left, int right, int[] temp){
         if (left < right){
             int mid = (left + right) / 2;
             mergeSort(arr, left, mid, temp);
             mergeSort(arr, mid + 1, right, temp);
 ​
             //到合并
             merge(arr, left, mid, right, temp);
         }
         return arr;
     }
     
     psvm
     int[] temp5 = new int[80000];
         for (int i = 0; i < 80000; i++) {
             temp5[i] = (int) (Math.random() * 8000000);
         }
         int[] temp6 = new int[temp5.length];
         System.out.println(Arrays.toString(mergeSort(temp5, 0, temp5.length - 1, temp6)));
         long date7 = System.currentTimeMillis();
         System.out.println("快速排序的运行时间为" + (date7 - date6) + "ms");

基数排序

  public static int[] radixSort(int[] arr){
         int max = arr[0];
         for (int i = 0; i < arr.length; i++) {
             if (arr[i] > max){
                 max = arr[i];
             }
         }
         int maxLength = (max + "").length();
 ​
         int[][] bucket = new int[10][arr.length];
 ​
         int[] bucketElementCounts = new int[10];
 ​
         for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
             for (int j = 0; j < arr.length; j++) {
                 int digitOfElment = arr[j] / n % 10;
                 bucket[digitOfElment][bucketElementCounts[digitOfElment]] = arr[j];
                 bucketElementCounts[digitOfElment]++;
             }
 ​
             int index = 0;
             for (int k = 0; k < bucketElementCounts.length; k++) {
                 if (bucketElementCounts[k] != 0){
                     for (int l = 0; l < bucketElementCounts[k]; l++) {
                         arr[index++] = bucket[k][l];
                     }
                 }
                 bucketElementCounts[k] = 0;
             }
         }
         return arr;
     }

堆排序

 //堆排序
     public static void heapSort(int[] arr){
         int temp = 0;
         for (int i = arr.length / 2 - 1; i >= 0 ; i--) {
             adjustHeap(arr, i, arr.length);
         }
         for (int j = arr.length - 1; j > 0 ; j--) {
             temp = arr[j];
             arr[j] = arr[0];
             arr[0] = temp;
             adjustHeap(arr, 0, j);
         }
         //System.out.println("堆排序的结果为:" + Arrays.toString(arr));
     }
     //将数组(二叉树),调整为大顶堆
     /*
     i表示非叶子几点在数组中的索引
     length表示对多少个元素继续调整,在逐渐减小
     */
     public static void adjustHeap(int[] arr, int i, int length){
         int temp = arr[i];
         for (int j = i * 2 + 1; j < length; j = j * 2 + 1) {
             //左子节点的值小于右子节点的值
             if (j + 1 < length && arr[j] < arr[j + 1]){
                 j++;
             }
             //子节点大于父节点
             if (arr[j] > temp){
                 arr[i] = arr[j];
                 i = j; //把较大的数赋值给当前节点
             }else {
                 break;
             }
         }
         //for循环结束时了,i为父节点树最大值放在了树顶
         arr[i] = temp; //将temp值放在调整后的位置上
     }

时间比较

 冒泡排序的运行时间为8356ms
 选择排序的运行时间为1584ms
 插入排序的运行时间为408ms
 希尔排序的运行时间为4797ms
 快速排序的运行时间为17ms
 归并排序的运行时间为14ms
 基数排序的运行时间为27ms
 堆排序的运行时间为11ms

二分查找

 public class Search {
     public static void main(String[] args) {
         int[] arr = {1, 3, 5, 6, 11, 11, 11, 33};
         //int index = binarySearch(arr, 0, arr.length - 1, 88);
         List<Integer> result = binarySearch(arr, 0, arr.length - 1, 11);
         System.out.println(result);
     }
 ​
     public static ArrayList<Integer> binarySearch(int[] arr, int left, int right, int value){
 ​
         if (left > right){
             return new ArrayList<Integer>();
         }
         int mid = (left + right) / 2;
         int midVal = arr[mid];
         if (value > midVal){
             return binarySearch(arr, mid + 1, right, value);
         }else if (value > midVal){
            return binarySearch(arr, left, mid - 1, value);
         }else {
             ArrayList<Integer> resIndexList = new ArrayList<>();
             int temp = mid - 1;
             while (true){
                 if (temp < 0 || arr[temp] != value){
                     break;
                 }
                 resIndexList.add(temp);
                 temp -= 1;
             }
 ​
             resIndexList.add(mid);
 ​
             temp = mid + 1;
             while (true){
                 if (temp > arr.length || arr[temp] != value){
                     break;
                 }
                 resIndexList.add(temp);
                 temp += 1;
             }
             return resIndexList;
         }
     }
 }
 ​

插值查找

关键字分布别叫均匀的速度非常快

 //插值查找算法
     public static int inserValueSearch(int[] arr, int left, int right, int findVal){
         System.out.println("ssss");
         if (left > right || findVal > arr[arr.length - 1] || findVal < arr[0]){
             return -1;
         }
 ​
         int mid = left + (right - left) * (findVal - arr[left]) / (arr[right] - arr[left]);
         int midVal = arr[mid];
         if (findVal > midVal){
             //向右边递归
             return inserValueSearch(arr, mid + 1, right, findVal);
         }else if (findVal <midVal){
             return inserValueSearch(arr, left, mid - 1, findVal);
         }else {
             return mid;
         }
     }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值