package Java_Interview_Book;
public class Order {
//选择排序,选出最小的与第一个位置交换。。。。。。
public static void selectSort(int[] a) {
int temp;//临时变量
int flag;//标记位置
int length = a.length;//数组长度
for(int i=0;i<length;i++) {
temp = a[i];
flag = i;
for(int j=i+1;j<length;j++) {
if(a[j] < temp) {
temp =a[j];//存储当前最小位置值
flag = j;//标记当前最小位置
}
}
if (flag != i) {//将第i小位置进行数值交换
a[flag] = a[i];
a[i] = temp;
}
}
}
//插入排序,每次加入的数和当前值比较,如果小和当前位置交换
public static void insertSort(int [] a) {
for (int i = 1; i < a.length; i++) {
int temp = a[i];
int j =i;
if(a[j-1] > temp) {
while(j >= 1 && a[j-1] > temp) {
a[j]=a[j-1];
j--;
}
}
a[j] = temp;
}
}
//(单向)冒泡排序,相邻两两比较,假设是小到大输出
public static void bubbleSort(int [] a ) {
int temp;
for (int i = 0; i < a.length; i++) {
for (int j = i+1; j < a.length; j++) {
if(a[i]>a[j]) {
temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
}
//两路归并算法,两个排好序的子序列合并为一个子序列
public static void merge(int []a,int left,int mid,int right){
int []tmp=new int[a.length];//辅助数组
int p1=left,p2=mid+1,k=left;//p1、p2是检测指针,k是存放指针
while(p1<=mid && p2<=right){
if(a[p1]<=a[p2])
tmp[k++]=a[p1++];
else
tmp[k++]=a[p2++];
}
while(p1<=mid) tmp[k++]=a[p1++];//如果第一个序列未检测完,直接将后面所有元素加到合并的序列中
while(p2<=right) tmp[k++]=a[p2++];//同上
//复制回原数组
for (int i = left; i <=right; i++)
a[i]=tmp[i];
}
public static void mergeSort(int [] a,int start,int end){
if(start<end){//当子序列中只有一个元素时结束递归
int mid=(start+end)/2;//划分子序列
mergeSort(a, start, mid);//对左侧子序列进行递归排序
mergeSort(a, mid+1, end);//对右侧子序列进行递归排序
merge(a, start, mid, end);//合并
}
}
//快排,以某个数作为基数,划分成数组,左边子数组每个元素都小于右边数组
public static void quickSort(int[] arr,int low,int high){
int i,j,temp,t;
if(low>high){
return;
}
i=low;
j=high;
temp = arr[low];//temp就是基准位
while (i<j) {
//先看右边,依次往左递减
while (temp<=arr[j]&&i<j) {
j--;
}
//再看左边,依次往右递增
while (temp>=arr[i]&&i<j) {
i++;
}
//如果满足条件则交换
if (i<j) {
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
//最后将基准为与i和j相等位置的数字交换
arr[low] = arr[j];
arr[j] = temp;
//递归调用左半数组
quickSort(arr, low, j-1);
//递归调用右半数组
quickSort(arr, j+1, high);
}
//希尔排序(缩小增量排序),分成几个子序列,对各个子序列之间进行直接插入排序
//设定一个增量,先从array[0]开始以为增量的进行直接插入排序,直到数组末尾..z直到array[n]
//然后取一个小于上一步增量的新的增量,直到增量小于1
public static void shellSort(int[] a){
int length = a.length;
int temp,j ;
for (int increPara = length/2; increPara > 0 ; increPara/=2) {
for (int i = increPara; i < length; i++) {
temp = a[i];
j = i -increPara;
while (j >= 0 && a[j] >= temp){
a[j+increPara]=a[j];
j-= increPara;
}
a[j+increPara] =temp;
}
}
}
//堆排序,大顶堆(r[i]>=r[2i] && r[i]>=r[2i+1])
//构建堆,将堆顶元素和最后一个元素位置进行交换
public static void maxHeapSort(int [] a) {
int arrayLength=a.length;
//循环建堆
for(int i=0;i<arrayLength-1;i++){
//建堆
buildMaxHeap(a,arrayLength-1-i);
//交换堆顶和最后一个元素
swap(a,0,arrayLength-1-i);
}
}
public static void buildMaxHeap(int[] data, int lastIndex){
for(int i=(lastIndex-1)/2;i>=0;i--){ //从最后一个非叶子结点开始建堆
int k=i; //k保存正在判断的节点
while(k*2+1<=lastIndex){ //如果当前k节点的子节点存在
int biggerIndex=2*k+1; //k节点的左子节点的索引
if(biggerIndex<lastIndex){ //如果biggerIndex小于lastIndex
if(data[biggerIndex]<data[biggerIndex+1]){ //若果右子节点的值较大
biggerIndex++; //biggerIndex总是记录较大子节点的索引
}
}
//如果k节点的值小于其较大的子节点的值
if(data[k]<data[biggerIndex]){
//交换他们
swap(data,k,biggerIndex);
//将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
k=biggerIndex;
}else{
break;
}
}
}
}
public static void swap(int [] a ,int i ,int j) {
a[i] = a[i] ^ a[j];
a[j] = a[i] ^ a[j];
a[i] = a[i] ^ a[j];
}
public static void main(String [] args) {
int a[] = {5,7,6,0,1,3,2};
// selectSort(a);
// insertSort(a);
// bubbleSort(a);
// mergeSort(a,0,a.length-1);
// quickSort(a,0,a.length-1);
// shellSort(a);
// maxHeapSort(a);
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
System.out.println("\n");
}
}
一、二分查找
package com.basic.order;
/**
* 又叫折半查找,要求待查找的序列有序。每次取中间位置的值与待查关键字比较,如果中间位置
* 的值比待查关键字大,则在前半部分循环这个查找的过程,如果中间位置的值比待查关键字小,
* 则在后半部分循环这个查找的过程。直到查找到了为止,否则序列中没有待查的关键字。
*
* @author hexiaoli
*
*/
public class BinarySearch {
public static int biSearch(int[] array, int a) {
int lo = 0;
int hi = array.length - 1;
int mid;
while (lo <= hi) {
mid = (lo + hi) >> 1;// 中间位置
if (array[mid] == a) {
return mid + 1;
} else if (array[mid] < a) { // 向右查找
lo = mid + 1;
} else { // 向左查找
hi = mid - 1;
}
}
return -1;
}
public static void main(String[] args) {
int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
System.out.println(biSearch(array, 2));
}
}
二、捅排序
package com.basic.order;
import java.util.ArrayList;
import java.util.Collections;
/**
* 桶排序的基本思想是: 把数组 arr 划分为 n 个大小相同子区间(桶),每个子区间各自排序,最 后合并 。
* 计数排序是桶排序的一种特殊情况,可以把计数排序当成每个桶里只有一个元素的情况。
* 1.找出待排序数组中的最大值 max、最小值 min
* 2.我们使用 动态数组 ArrayList 作为桶,桶里放的元素也用 ArrayList 存储。桶的数量为(maxmin)/arr.length+1
* 3.遍历数组:arr,计算每个元素 arr[i] 放的桶 4.每个桶各自排序
*
* @author hexiaoli
*
*/
public class BucketSort {
public static ArrayList<ArrayList<Integer>> bucketSort(int[] arr) {
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (int i = 0; i < arr.length; i++) {
max = Math.max(max, arr[i]);
min = Math.min(min, arr[i]);
}
// 创建桶
int bucketNum = (max - min) / arr.length + 1;
ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
for (int i = 0; i < bucketNum; i++) {
bucketArr.add(new ArrayList<Integer>());
}
// 将每个元素放入桶
for (int i = 0; i < arr.length; i++) {
int num = (arr[i] - min) / (arr.length);
bucketArr.get(num).add(arr[i]);
}
// 对每个桶进行排序
for (int i = 0; i < bucketArr.size(); i++) {
Collections.sort(bucketArr.get(i));
}
int index = 0;
for (ArrayList<Integer> bucket : bucketArr) {
for (Integer i : bucket) {
arr[index++] = i;
}
}
return bucketArr;
}
public static void main(String[] args) {
int[] array = { 1, 4, 5, 9, 8, 7, 5, 3, 2 };
bucketSort(array);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
}
}