数组高级应用—排序与查找

1、数组排序

  1)冒泡排序

/**
 * 冒泡排序基本概念是:
 * 依次比较相邻的两个数,将小数放在前面,大数放在后面。
 * 即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。
 * 然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,
 * 直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,
 * 将最大的数放到了最后。在第二趟:仍从第一对数开始比较
 * (因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),
 * 将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),
 * 第二趟结束,在倒数第二的位置上得到一个新的最大数
 * (其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。
 */
class BubbleSort {
    public static void bubbleSort(int[] arr){
        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]){
                    SortTest.swap(arr,j,j+1);
                }
            }
        }
    }
}

  2)选择排序

/**
 *
 * 选择排序基本思路:
 * 把第一个元素依次和后面的所有元素进行比较。
 * 第一次结束后,就会有最小值出现在最前面。
 * 依次类推
 */
 public class SelectSort {
    public static void selectSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            int minFlag = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[minFlag] > arr[j]) {
                    minFlag = j;
                }
            }
            if (i != minFlag) {
                SortTest.swap(arr, i, minFlag);
            }
        }
    }
}

   3)插入排序

/**
 *
 * 插入排序基本思想
 * 将n个元素的数列分为已有序和无序两个部分,如插入排序过程示例下所示:   
 * {{a1},{a2,a3,a4,…,an}}   
 * {{a1⑴,a2⑴},{a3⑴,a4⑴ …,an⑴}}  
 * {{a1(n-1),a2(n-1) ,…},{an(n-1)}}   
 * 每次处理就是将无序数列的第一个元素与有序数列的元素从后往前逐个进行比较,
 * 找出插入位置,将该元素插入到有序数列的合适位置中。
 */
public class InsertSort {
    public static void insertSort(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            for (int j = i - 1; j >= 0; j--) {
                if(arr[j] > arr[j+1]){
                    SortTest.swap(arr,j,j+1);
                }
            }
        }
    }
}

  4)希尔排序

/**
 *
 * 希尔排序:先取一个小于n的整数d1作为第一个增量,
 * 把文件的全部记录分成(n除以d1)个组。所有距离为d1的倍数的记录放在同一个组中。
 * 先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,
 * 直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
 */
/**
 * 属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序
 * 排序过程:先取一个正整数d1<n,把所有序号相隔d1的数组元素放一组,
 * 组内进行直接插入排序;然后取d2<d1,重复上述分组和排序操作;直至di=1, 即所有记录放进一个组中排序为止
 * 初始:d=5   49 38 65 97 76 13 27 49 55 04
 * 49 13       |--------------|
 * 38 27            |--------------|
 * 65 49             |--------------|
 * 97 55                  |--------------|
 * 76 04                    |--------------|
 * 一趟结果   13 27 49 55 04 49 38 65 97 76
 * d=3       13 27 49  55 04 49 38 65 97 76
 * 13 55 38 76 |---------|--------|--------|
 * 27 04 65       |---------|--------|
 * 49 49 97          |----------|--------|
 * 二趟结果  13 04 49* 38 27 49 55 65 97 76
 * d=1   13  04  49  38  27  49  55  65  97  76
 *       |---|---|---|---|---|---|---|---|---|    三趟结果
 * 04 13 27 38 49 49 55 65 76 97
 */

public class ShellSort {
    public static void shellSort(int[] arr) {
        for (int i = arr.length / 2; i > 2; i = i / 2) {
            for (int j = 0; j < i; j++) {
                insertSort(arr, j, i);
            }
        }
        insertSort(arr, 0, 1);
    }

    public static void insertSort(int[] arr, int start, int inc) {
        for(int i = start+inc; i < arr.length;i+=inc){
            for(int j = i-inc; j >= 0; j-=inc){
                if(arr[j] > arr[j+inc]){
                    SortTest.swap(arr,j,j+inc);
                }
            }
        }
    }
}

  5)快速排序

/**
 * 快速排序:
 * 一趟快速排序的算法是:
 * 1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
 * 2)以第一个数组元素作为关键数据,赋值给key,即 key=A[0];
 * 3)从j开始向前搜索,即由后开始向前搜索(j=j-1即j--),
 * 找到第一个小于key的值A[j],A[i]与A[j]交换;
 * 4)从i开始向后搜索,即由前开始向后搜索(i=i+1即i++),
 * 找到第一个大于key的A[i],A[i]与A[j]交换;
 * 5)重复第3、4、5步,直到 I=J;
 * (3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。
 * 找到并交换的时候i, j指针位置不变。
 * 另外当i=j这过程一定正好是i+或j-完成的最后令循环结束。)
 */
public class QuickSort {
    public static void quinckSort(int[] arr) {
        sort(arr, 0, arr.length - 1);
    }

    public static void sort(int[] arr, int i, int j) {
        int pivotIndex = partition(arr,i,j);
        if(i < j){
            sort(arr,i,pivotIndex-1);
            sort(arr,pivotIndex+1,j);
        }
    }
    public static int partition(int[] array, int low, int high){
        int pivokey = array[low];
        while(low < high){
            while(low < high && array[high] >= pivokey)
            {
                high--;
            }
            array[low] = array[high];
            while(low < high && array[low] <= pivokey)
            {
                low++;
            }
            array[high] = array[low];
        }
        array[low] = pivokey;
        return low;
    }
}

  6)归并排序

/**
 *
 * 归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。   
 * 如设有数列{6,202,100,301,38,8,1}   
 * 初始状态: [6] [202] [100] [301] [38] [8] [1] 比较次数   
 * i=1 [6 202 ] [ 100 301] [ 8 38] [ 1 ] 3   
 * i=2 [ 6 100 202 301 ] [ 1 8 38 ] 4   
 * i=3 [ 1 6 8 38 100 202 301 ] 4
 */
public class MergeSort {
    public static void mergeSort(int[] arr){
        sort(arr,0,arr.length-1);
    }
    public static void sort(int[] arr,int low, int high){
        int mid = (low + high) / 2;
        if (low < high) {
            // 左边
            sort(arr, low, mid);
            // 右边
            sort(arr, mid + 1, high);
            // 左右归并
            merge(arr, low, mid, high);
        }
    }
    public static void merge(int[] arr, 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 (arr[i] < arr[j]) {
                temp[k++] = arr[i++];
            } else {
                temp[k++] = arr[j++];
            }
        }
        // 把左边剩余的数移入数组
        while (i <= mid) {
            temp[k++] = arr[i++];
        }
        // 把右边边剩余的数移入数组
        while (j <= high) {
            temp[k++] = arr[j++];
        }
        // 把新数组中的数覆盖nums数组
        for (int k2 = 0; k2 < temp.length; k2++) {
            arr[k2 + low] = temp[k2];
        }
    }
}

  7)堆排序

public class HeapSort {
    public static void heapSort(int[] arr) {
        buildHeap(arr); // 建立堆
        int i = 0;
        for (i = arr.length - 1; i >= 1; i--) {
            SortTest.swap(arr, 0, i);
            heapify(arr, 0, i);
        }
    }

    public static void buildHeap(int[] arr) {
        int n = arr.length;
        for (int i = n / 2 - 1; i >= 0; i--) {
            heapify(arr, i, n);
        }
    }

    public static void heapify(int[] arr, int idx, int max) {
        int left = 2 * idx + 1;
        int rigth = 2 * idx + 2;
        int largest = 0;
        if (left < max && arr[left] > arr[idx])
            largest = left;
        else
            largest = idx;
        if (rigth < max && arr[rigth] > arr[largest])
            largest = rigth;
        if (largest != idx) {
            SortTest.swap(arr, largest, idx);
            heapify(arr, largest, max);
        }
    }
}

2、数组二分查找

public class BinarySearch {
    public static void main(String[] args) {
        int[] arr = {11, 22, 33, 44, 55, 66, 77, 88, 99};
        int index = binarySearch(arr, 88);
        System.out.println("index:" + index);
        index = binarySearch(arr, 100);
        System.out.println("index:" + index);
    }

    public static int binarySearch(int[] arr, int value) {
        int low = 0;
        int high = arr.length - 1;
        int mid = -1;
        while (low < high) {
            mid = (low + high) / 2;
            if (arr[mid] == value){
                return mid;
            }
            if (value > arr[mid])
                low = mid + 1;
            else
                high = mid - 1;
        }
        return -1;
    }
}
时间: 2024-10-10 22:17:30

数组高级应用—排序与查找的相关文章

数组的高级(排序和查找)

1.冒泡排序:相邻元素两两比较,大的向后方法,第一次完毕后,最大值就出现在了最大索引出.同理,继续,即可得到一个排好序的数组. 2.冒泡排序的规则: 1).两两比较,大的往后方法. 2).第一次比较完毕后,下一次比较的时候就会减少一个元素的比较. 3).第一次比较,有0个元素不比. 第二次比较,有1个元素不比. 第三次比较,有2个元素不比. ...... 4).总共需要比较数组的长度-1次. 3.冒泡排序图解 4.代码实现 package cn; /**  * 数组排序之冒泡排序   */ pu

数组高级部分--排序,查找

1.数组排序之冒泡排序: 两两比较,大的往后放放,第一次比较完毕之后,最大值就出现在了最大索引出,继续依次比较,得到一个排好序的数组! 2.数组排序之:选择排序:           用0索引依次和后面的索引进行比较,第一次比较完毕之后,最小值出现在了最小索处!               同理,其他索引也是依次进行比较! 3.数组查找 基本查找:数组元素查表法(查询数组中的元素第一次在数组中出现的索引):从头查到尾                     数组二分查找(折半查找) 思路:   

java 数组比较,元素的比较,Comparable,Comparator比较的应用实现,排序,查找示例

java 数组比较,元素的比较,自定义Comparator的实现,排序,查找示例 package org.rui.array.compar; import java.util.Arrays; import java.util.Random; import org.rui.generics.anonymity.Generator; /** * 程序设计的基本目标是"将保持不变的事物与会发生改变的事物相分离" * 而这是,不变的是通用的排序算法,变化的是各种对象相互比较的方式, * 因此,

数组的排序与查找

/**对如下一个数组int[] iarr={34,67,1,56,32,78,12,45,79,4,57,102,123,3};进行排序(采用自己擅长的排序算法),然后查询排序之后的采用二分查找*法查找45在在数组的索引值 ,排序.查找封装成方法,然后在main方法中调用测试.*/ public class FenDou01 { public static void main(String[] args) { int[] iarr={34,67,1,56,32,78,12,45,79,4,57,

(八)数组以及排序和查找

JavaSE(八) --数组以及排序和查找 一.数组的定义 三种定义方法: int b[]=new int[5]; Int []b=new int[5]; int[] a=new int[5]; (建议使用这种定义方法) //必须规定数组长度,因为在编译的时候就要分配内存. 我们也可以在定义的时候就初始化数组 Int[] a={1,2,3,3,5}; 这默认了数组a的长度是5. 分配内存详情如下: 开辟一块内存,有5个小块,a指向数组的首地址. int[][] b=new int[5][];  

所有的排序、查找算法

import javax.mail.Part; /** * 顺序查找.排序 * * @author 曾修建 * @version 创建时间:2014-7-30 下午04:15:10 */ public class SequentialSearch { public static void main(String[] args) { Integer[] a = {1,2,3,4,5,7,6,88}; //二分查找非递归 System.out.println( "二分查找非递归实现 位置 : &qu

OC基础第五讲--Block、数组高级、字面量

Block 1.1block与函数指针 函数: int sum(int x, int y) { retrun x + y; } 函数指针: 把上面函数原型int sum(int x, int y)中的函数名替换成(*p),即可得到一个函数指针int (*p)(int x, int y). 这个函数表示指针p指向一个函数,这个函数有两个int型参数,返回值是int类型. Block:把函数指针int (*p)(int x, int y)中的'*'换成'^'就是我们block的声明,即int (^p

希尔排序(插入排序)-八大排序三大查找汇总(5)

基本思想 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序. 稳定性 由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的. 时间复杂度 希尔排序的时间复杂度取决于步长的选择. 平均情况下,

排序和查找算法的使用

TBOX提供了各种常用算法,对容器中的元素进行各种操作,这里主要介绍下排序和查找算法. 排序算法目前支持如下几种: 快速排序:tb_quick_sort 堆排序: tb_heap_sort 插入排序:tb_bubble_sort 冒泡排序:tb_insert_sort 并且提供通用的tb_sort接口,对各种排序算法进行自动适配,使得任何情况下,性能都是最优的. 例如: 对具有随机迭代特性的容器,采用库快速排序来优化 对具有随机迭代特性,并且是超大规模的容器,采用堆排序 对只能线性迭代的容器采用