您的位置 首页 java

常用查找和排序汇总(欢迎收藏)

package com.itwang.sort_search;
/**
 * @ProjectName: JavaPractice
 * @Package: com.itwang.sort_search
 * @ClassName: BinarySearch
 * @Author: JikeWang
 * @Description: 二分查找
 * @Date: 2018-08-28 21:21
 * @Version: 1.0
 */public class Search {
 /**
 * @Method find
 * @Author JikeWang
 * @Version 1.0
 * @Description 顺序查找
 * @param array 要查找的元素数组
 * @param key 要查找的元素
 * @Return int 返回查找结果 -1:表示没有查找到 0~array.length-1: 表示查找到
 * @ Exception 
 * @Date 2018-08-30 18:42
 */ public int find(int[] array, int key){
 int i;
 for (i = 0 ;i < array.length; i++){
 if (array[i] == key){
 break;
 }
 }
 if (i == array.length){
 return -1;//如果没有查找到
 }else{
 return i;//如果查找到
 }
 }
 /**
 * @Method binarySearch
 * @Author JikeWang
 * @Version 1.0
 * @Description 二分查找( 折半查找 )前提元素必须是有序的
 * @param array 要查找的数组
 * @param key 要查找的关键元素
 * @Return int 返回的查找结果,如果找到则返回元素的位置,如果没有找到则返回元素应该插入的位置
 * @Exception
 * @Date 2018-08-28 21:28
 */ public int binarySearch(int[] array, int key){
 int low = 0, high = array.length - 1;
  while  (low <= high){
 int mid = (high + low) >> 1;
 if (array[mid] < key){
 low = mid + 1;
 }else if (array[mid] > key){
 high = mid - 1;
 }else {
 return mid;
 }
 }
 return low;
 }
 /********************************插入排序********************************/ /**
 * @Method insertSort
 * @Author JikeWang
 * @Version 1.0
 * @Description 直接插入排序
 * @param array 要排序的数组集合
 * @Return void
 * @Exception
 * @Date 2018-08-30 18:44
 */ void insertSort(int[] array){
 //直接插入排序,假定前面是有序的,从1后面位置开始插入排序
 System.out.println("---------直接插入排序---------");
 for (int i = 1; i < array.length; i++){
 int tmp = array[i];
 int j = i - 1;
 //遍历找到插入的位置
 while ((j >= 0) && (tmp < array[j])){
 array[j + 1] = array[j];//如果插入的元素小于当前元素,元素后移
 j--;
 }
 //将要插入的元素插入到找到的位置(j+1)是由于上面循环结束后减了一次1
 array[j + 1] = tmp;
 }
 }
 /**
 * @Method binaryInsertSort
 * @Author JikeWang
 * @Version 1.0
 * @Description 折半插入排序(跟直接插入排序一样,只是在查找元素插入位置的时候利用了折半查找
 * @param array 要排序的数组集合
 * @Return void
 * @Exception
 * @Date 2018-08-30 18:45
 */ void binaryInsertSort(int[] array){
 System.out.println("---------折半插入排序---------");
 for (int i = 1; i < array.length; i++){
 int tmp = array[i];
 int low = binarySearch(array,tmp);
 //元素后移
 for (int j = i - 1; j >= low; j --){
 array[j+1] = array[j];
 }
 array[low] = tmp;
 }
 }
 /**
 * @Method shellSort
 * @Author JikeWang
 * @Version 1.0
 * @Description 希尔排序(先将整个待排序记录序列分割成若干子序列,分别进行直接插入排序,
 * 待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序)
 * 分割序列可以根据某一增量进行分割
 * @param array
 * @Return void
 * @Exception
 * @Date 2018-08-30 18:49
 */ public void shellSort(int[] array){
 //增量每次都是/2
 for (int step = array.length / 2; step > 0; step /= 2){
 //从增量那组开始进行插入排序,直至完毕
 for (int i = step; i < array.length; i++){
 int j = i;
 int tmp = array[j];
 //j-step就是代表与它同组隔壁的元素
 while (j - step >= 0 && tmp < array[j - step]){
 array[j] = array[j - step];
 j = j - step;
 }
 array[j] = tmp;
 }
 }
 }
 /********************************交换排序********************************/ /**
 * @Method bubbleSort
 * @Author JikeWang
 * @Version 1.0
 * @Description 冒泡排序,每次循环通过比较相邻的元素大小进行交换,最终会是最后一个元素时最大的。
 * 第一轮,需要循环n-1次,最后一个元素最大,
 * 第二轮,需要循环n-2次,最后一个元素最大,
 * 以此类推,需要进行n轮,每轮循环n-i次
 * @param array
 * @Return void
 * @Exception
 * @Date 2018-08-30 18:57
 */ public void bubbleSort(int[] array){
 System.out.println("---------冒泡排序---------");
 //进行array.length次循环,每轮进行array.length - i次循环
 for (int i = 1; i <= array.length; i++){
 boolean flag = true;
 //设定一个标记,若为true,则表示此次循环
 //没有进行交换,否则有交换
 for (int j = 0; j < array.length - i; j++){
 if (array[j] > array[j + 1]){
 swap(array, j, j+1);
 flag = false;
 }
 }
 }
 }
 /**
 * @Method quickSort
 * @Author JikeWang
 * @Version 1.0
 * @Description 快速排序(快速排序是对冒泡排序的一种改进,通过一趟排序将待排序列分割成独立的两部分,
 * 其中一部分记录的关键字均比另一部分记录关键字小,然后分别对这两部分记录进行排序)
 * @param array
 * @param low
 * @param high
 * @Return void
 * @Exception
 * @Date 2018-08-30 19:01
 */ public void quickSort(int[] array, int low, int high){
 if (low >= high){
 return;
 }
 int index = partition(array, low, high);
 quickSort(array, low, index - 1);
 quickSort(array, index + 1, high);
 }
 public int partition(int[] array, int low, int high) {
 //以第一个元素作为枢轴值
 int key = array[low];
 while (low < high){
 //从后半部分向前扫描
 while (array[high] >= key && low < high) high--;
 //将后半部分小于枢轴值的元素放到前半部分
 array[low] = array[high];
 //从前半部分向后扫描
 while (array[low] <= key && low < high) low++;
 //将前半部分大于枢轴值的元素放到后半部分
 array[high] = array[low];
 }
 array[low] = key;
 return low;
 }
 /********************************选择排序********************************/ /**
 * @Method selectSort
 * @Author JikeWang
 * @Version 1.0
 * @Description 简单选择排序(每一次首先选择当前索引位置的元素是最小值,通过跟后面元素的比较,确定最小元素位置,
 * 如果最小位置发生变化,则将最小位置的元素赋值到当前选择的位置)
 * @param array
 * @Return void
 * @Exception
 * @Date 2018-08-30 19:01
 */ public void selectSort(int[] array){
 System.out.println("---------简单选择排序---------");
 for (int i = 0; i < array.length - 1; i++){
 int min = i;
 //每一趟循环比较,找到最小的元素的下标并赋值给min
 for (int j = i + 1;j < array.length; j++){
 if (array[j] < array[min])
 min = j;
 }
 //如果min发生变化,进行交换
 if (min != i){
 swap(array, min, i);
 }
 }
 }
 //构建大顶堆
 public int[] buildMaxHeap(int[] array){
 for (int i = array.length / 2 - 1;i >= 0;i--){
 //从第一个非叶子节点从下至上,从右至左调整结构
 adjustDownHeap(array, i, array.length);
 }
 return array;
 }
 //向下调整堆
 private void adjustDownHeap(int[] array, int k, int length) {
 //取出当前元素
 int tmp = array[k];
 //i为初始化为节点k的左孩子,沿节点较大的子节点向下调整
 for (int i = 2*k + 1; i < length - 1; i = 2*i + 1 ){
 if (i < length && array[i] < array[i+1])//取节点较大的子节点的下标
 i++;//如果节点的右孩子>左孩子,则取右孩子节点的下标
 if (array[i] <= tmp) break;//根节点 >=左右子女中关键字较大者,调整结束
 else{ //根节点 <左右子女中关键字较大者
 array[k] = array[i];//将左右子结点中较大值array[i]调整到双亲节点上
 k = i; //【关键】修改k值,以便继续向下调整
 }
 }
 array[k] = tmp;//被调整的结点的值放人最终位置
 }
 /**
 * @Method heapSort
 * @Author JikeWang
 * @Version 1.0
 * @Description 堆排序(堆排序首先需要构建堆,这里是构建大顶堆,构建完毕后需要将元素从小到大整理出来,
 * 因为堆顶元素时最大值,通过从后向前操作,每次将堆顶元素赋值到当前位置,但每次赋值后,
 * 堆的结构就发生了变化,需要重新调整)
 * @param array
 * @Return void
 * @Exception
 * @Date 2018-08-30 19:01
 */ public void heapSort(int[] array){
 array = buildMaxHeap(array);
 //n-1趟的交换和建堆过程
 for (int i = array.length - 1; i > 1;i--){
 swap(array, 0, i);//将堆顶元素和堆低元素交换
 adjustDownHeap(array, 0, i);//整理、将剩余的元素整理成堆
 }
 }
 /**
 * @Method deleteMax
 * @Author JikeWang
 * @Version 1.0
 * @Description 删除堆顶元素操作
 * @param array
 * @Return int[]
 * @Exception
 * @Date 2018-08-30 19:02
 */ public int[] deleteMax(int[] array){
 //将堆的最后一个元素与堆顶元素交换,堆底元素值设为-999996
 array[0] = array[array.length-1];
 array[array.length-1] = -99999;
 //对此时的根节点进行向下调整
 adjustDownHeap(array, 0, array.length);
 return array;
 }
 /**
 * @Method insertData
 * @Author JikeWang
 * @Version 1.0
 * @Description 插入操作:向大根堆array中插入数据data
 * @param array
 * @param data
 * @Return int[]
 * @Exception
 * @Date 2018-08-30 19:02
 */ public int[] insertData(int[] array, int data){
 array[array.length-1] = data; //将新节点放在堆的末端
 int k = array.length-1; //需要调整的节点
 int parent = (k-1)/2; //双亲节点
 while(parent >=0 && data>array[parent]){
 array[k] = array[parent]; //双亲节点下调
 k = parent;
 if(parent != 0){
 parent = (parent-1)/2; //继续向上比较
 }else{ //根节点已调整完毕,跳出循环
 break;
 }
 }
 array[k] = data; //将插入的结点放到正确的位置
 return array;
 }
 //两个位置的元素交换值
 private void swap(int[] array, int j, int i) {
 int tmp = array[j];
 array[j] = array[i];
 array[i] = tmp;
 }
 //打印元素
 void print(int[] array){
 for (int a : array) {
 System.out.print(a + "t");
 }
 System.out.println();
 }
 public static void main(String[] args) {
 int[] array = {2,5,7,9,24};
 int[] sort_array = {2,5,3,1};
 Search search = new Search();
 //二分查找(折半查找)
 int result = search.binarySearch(array, 10);
 System.out.println(result);
 //直接插入排序
 //search.insertSort(sort_array);
 //折半插入排序
 //search.binaryInsertSort(sort_array);
 //冒泡排序
 //search.binaryInsertSort(sort_array);
 //简单选择排序
 //search.selectSort(sort_array);
 //希尔排序
 //search.shellSort(sort_array);
 //快速排序
 //search.quickSort(sort_array, 0, sort_array.length - 1);
 search.heapSort(sort_array);
 search.print(sort_array);
 }
}
 

文章来源:智云一二三科技

文章标题:常用查找和排序汇总(欢迎收藏)

文章地址:https://www.zhihuclub.com/199493.shtml

关于作者: 智云科技

热门文章

网站地图