publicstaticint[]ShellSort(int[] array){int len = array.length;int temp, gap = len /2;while(gap >0){for(int i = gap; i < len; i++){
temp = array[i];int preIndex = i - gap;while(preIndex >=0&& array[preIndex]> temp){
array[preIndex + gap]= array[preIndex];
preIndex -= gap;}
array[preIndex + gap]= temp;}
gap /=2;}return array;}
递归排序
importorg.junit.Test;importjava.util.Arrays;publicclass 归并排序 {//1 两个有序数组a,b合并成cstaticint[]sum(int[] a,int alen,int[] b,int blen,int[] c){//初始化三个指针对应三个数组int i,j,k;
i=j=k=0;//循环直到i或j越界while(i<alen && j<blen){if(a[i]<b[j]){//先放小的数,放完+1
c[k++]=a[i++];}else{
c[k++]=b[j++];}}//经过上边的循环后的i,j如果还有元素,直接放进去while(i<alen){
c[k++]=a[i++];}while(j<blen){
c[k++]=b[j++];}return c;}@Testpublicvoida1(){int[] a={1,3,5,7,9};int[] b={2,4,6,8,10,12,14};int[] c=newint[a.length+b.length];int[] sum =sum(a, a.length, b, b.length, c);System.out.println(Arrays.toString(sum));}//2 归并排序//递归,将数组分为两组,判断是否有序,无序继续分两组,直到有序@Testpublicvoida2(){int[] arr={4,5,2,3,6,8,0,9,1,7};//start=1从第二个元素开始比较int[] res =merge(arr,1, arr.length);System.out.println(Arrays.toString(res));}//合并方法publicint[]merge(int[] data,int start,int end){if(start<end){//取中间点作分组尝试int mid=(start+end)/2;//递归再二分merge(data,start,mid);merge(data,mid+1,end);//调用分组方法System.out.println(Arrays.toString(data));part(data,start,mid,end);}return data;}//分两组方法publicvoidpart(int[] data,int start,int mid,int end){//分两组A和B,长度分别为中间到左右端长度int lena=mid-start+1;//start从1开始,要把这个长度补上int lenb=end-mid;int[]A=newint[lena+1];//左数组int[]B=newint[lenb+1];//右数组//分别遍历数组A和B,将给定数组的左右元素分别插入对应位置for(int i =0; i < lena; i++){A[i]= data[i+start-1];}A[lena]=Integer.MAX_VALUE;//将数组A的最后一个元素赋值为最大整数System.out.println("A:"+Arrays.toString(A));for(int i =0; i < lenb; i++){B[i]= data[i+mid];}B[lenb]=Integer.MAX_VALUE;System.out.println("B:"+Arrays.toString(B));//此时左右两个数组已经是有序的,依次比较放入小数即可int m=0;int n=0;for(int i = start-1; i < end; i++){if(A[m]>B[n]){//先放小的数
data[i]=B[n++];}else{
data[i]=A[m++];}}//最终返回的数组长度依然为初始长度,因此追加的两个最大整数会在A,B的最后被抛弃}}
归并排序
/**
* 归并排序
*
* @param array
* @return
*/publicstaticint[]MergeSort(int[] array){if(array.length <2)return array;int mid = array.length /2;int[] left =Arrays.copyOfRange(array,0, mid);int[] right =Arrays.copyOfRange(array, mid, array.length);returnmerge(MergeSort(left),MergeSort(right));}/**
* 归并排序——将两段排序好的数组结合成一个排序数组
*
* @param left
* @param right
* @return
*/publicstaticint[]merge(int[] left,int[] right){int[] result =newint[left.length + right.length];for(int index =0, i =0, j =0; index < result.length; index++){if(i >= left.length)
result[index]= right[j++];elseif(j >= right.length)
result[index]= left[i++];elseif(left[i]> right[j])
result[index]= right[j++];else
result[index]= left[i++];}return result;}
堆排序
//声明全局变量,用于记录数组array的长度;staticint len;/**
* 堆排序算法
*
* @param array
* @return
*/publicstaticint[]HeapSort(int[] array){
len = array.length;if(len <1)return array;//1.构建一个最大堆buildMaxHeap(array);//2.循环将堆首位(最大值)与末位交换,然后在重新调整最大堆while(len >0){swap(array,0, len -1);
len--;adjustHeap(array,0);}return array;}/**
* 建立最大堆
*
* @param array
*/publicstaticvoidbuildMaxHeap(int[] array){//从最后一个非叶子节点开始向上构造最大堆for(int i =(len/2-1); i >=0; i--){//感谢 @让我发会呆 网友的提醒,此处应该为 i = (len/2 - 1) adjustHeap(array, i);}}/**
* 调整使之成为最大堆
*
* @param array
* @param i
*/publicstaticvoidadjustHeap(int[] array,int i){int maxIndex = i;//如果有左子树,且左子树大于父节点,则将最大指针指向左子树if(i *2< len && array[i *2]> array[maxIndex])
maxIndex = i *2;//如果有右子树,且右子树大于父节点,则将最大指针指向右子树if(i *2+1< len && array[i *2+1]> array[maxIndex])
maxIndex = i *2+1;//如果父节点不是最大值,则将父节点与最大值交换,并且递归调整与父节点交换的位置。if(maxIndex != i){swap(array, maxIndex, i);adjustHeap(array, maxIndex);}}
计数排序
publicstaticint[]CountingSort(int[] array){if(array.length ==0)return array;int bias, min = array[0], max = array[0];for(int i =1; i < array.length; i++){if(array[i]> max)
max = array[i];if(array[i]< min)
min = array[i];}
bias =0- min;int[] bucket =newint[max - min +1];Arrays.fill(bucket,0);for(int i =0; i < array.length; i++){
bucket[array[i]+ bias]++;}int index =0, i =0;while(index < array.length){if(bucket[i]!=0){
array[index]= i - bias;
bucket[i]--;
index++;}else
i++;}return array;}
桶排序
publicstaticArrayList<Integer>BucketSort(ArrayList<Integer> array,int bucketSize){if(array ==null|| array.size()<2)return array;int max = array.get(0), min = array.get(0);// 找到最大值最小值for(int i =0; i < array.size(); i++){if(array.get(i)> max)
max = array.get(i);if(array.get(i)< min)
min = array.get(i);}int bucketCount =(max - min)/ bucketSize +1;ArrayList<ArrayList<Integer>> bucketArr =newArrayList<>(bucketCount);ArrayList<Integer> resultArr =newArrayList<>();for(int i =0; i < bucketCount; i++){
bucketArr.add(newArrayList<Integer>());}for(int i =0; i < array.size(); i++){
bucketArr.get((array.get(i)- min)/ bucketSize).add(array.get(i));}for(int i =0; i < bucketCount; i++){if(bucketSize ==1){// 如果带排序数组中有重复数字时 感谢 @见风任然是风 朋友指出错误for(int j =0; j < bucketArr.get(i).size(); j++)
resultArr.add(bucketArr.get(i).get(j));}else{if(bucketCount ==1)
bucketSize--;ArrayList<Integer> temp =BucketSort(bucketArr.get(i), bucketSize);for(int j =0; j < temp.size(); j++)
resultArr.add(temp.get(j));}}return resultArr;}
基数排序
publicstaticint[]RadixSort(int[] array){if(array ==null|| array.length <2)return array;// 1.先算出最大数的位数;int max = array[0];for(int i =1; i < array.length; i++){
max =Math.max(max, array[i]);}int maxDigit =0;while(max !=0){
max /=10;
maxDigit++;}int mod =10, div =1;ArrayList<ArrayList<Integer>> bucketList =newArrayList<ArrayList<Integer>>();for(int i =0; i <10; i++)
bucketList.add(newArrayList<Integer>());for(int i =0; i < maxDigit; i++, mod *=10, div *=10){for(int j =0; j < array.length; j++){int num =(array[j]% mod)/ div;
bucketList.get(num).add(array[j]);}int index =0;for(int j =0; j < bucketList.size(); j++){for(int k =0; k < bucketList.get(j).size(); k++)
array[index++]= bucketList.get(j).get(k);
bucketList.get(j).clear();}}return array;}
二分查找
//二分查找法publicclass 二分查找 {publicstaticinta1(int key){//从升序排序的数组中查找KEY所在索引int[] arr=newint[]{0,1,2,3,4,5,6,7,8,9};//初始化查找的起点和终点int end=arr.length-1;int start=0;while(start<=end){//每次都从中间开始找int mid=(end+start)/2;if(arr[mid]==key){return mid;}elseif(arr[mid]>key){//中间数大于key,就找比中间数小的
end = mid;}else{
start = mid;}}return-1;//表示未找到}publicstaticvoidmain(String[] args){int i =a1(4);System.out.println(i);}}
找出数组中第二大的数
importorg.junit.Test;//找出数组中第二大的数publicclass 第二大的数 {//判断一个数组中第二大的数@Testpublicvoida1(){String str="3 4 2 5 1 6 7 8";String[] strs = str.split("\\s");int[] arr=newint[strs.length];//转换字符串数组到整数数组for(int i =0; i < arr.length; i++){
arr[i]=Integer.parseInt(strs[i]);}//初始化最大数为数组第一个数int max=arr[0];int sec=0;for(int i =0; i < arr.length; i++){//遍历数组,如果有数比第二大的数大,就进入交换if(arr[i]>sec){//如果这个数比第二和第一都大,就赋值第二大数为最大数,最大数为该数if(arr[i]>max){
sec=max;
max=arr[i];}else{//如果只比第二大数大,比第一大数小,就直接赋值给第二大数
sec=arr[i];}}}System.out.println("最大的数:"+max+",第二大的数:"+sec);}}
求一个整数的阶乘
//数的阶乘,递归publicclass 阶乘 {publicstaticinta1(int num){if(num<=0){return0;}elseif(num==1){return1;}else{return num*a1(num-1);}}publicstaticvoidmain(String[] args){int i =a1(3);System.out.println(i);}}
斐波那契数列
//除第一个和第二个数外,任意一个数都可由前两个数相加得到publicclassFibonacciDemo{publicstaticArrayList<Integer>fib(int size){int a =0;int b =1;//中间结果标记int n =0;//数组长度计数器int len =0;ArrayList<Integer> nums =newArrayList<>();while(len <= size){
len++;
n = a + b;
nums.add(n);
a = b;
b = n;}return nums;}publicstaticvoidmain(String[] args){ArrayList<Integer> fibList =fib(10);System.out.println(fibList);}}
雪花算法
publicclassIdWorker{//因为二进制里第一个 bit 为如果是 1,那么都是负数,但是我们生成的 id 都是正数,所以第一个 bit 统一都是 0。//机器ID 2进制5位 32位减掉1位 31个privatelong workerId;//机房ID 2进制5位 32位减掉1位 31个privatelong datacenterId;//代表一毫秒内生成的多个id的最新序号 12位 4096 -1 = 4095 个privatelong sequence;//设置一个时间初始值 2^41 - 1 差不多可以用69年privatelong twepoch =1585644268888L;//5位的机器idprivatelong workerIdBits =5L;//5位的机房idprivatelong datacenterIdBits =5L;//每毫秒内产生的id数 2 的 12次方privatelong sequenceBits =12L;// 这个是二进制运算,就是5 bit最多只能有31个数字,也就是说机器id最多只能是32以内privatelong maxWorkerId =-1L^(-1L<< workerIdBits);// 这个是一个意思,就是5 bit最多只能有31个数字,机房id最多只能是32以内privatelong maxDatacenterId =-1L^(-1L<< datacenterIdBits);privatelong workerIdShift = sequenceBits;privatelong datacenterIdShift = sequenceBits + workerIdBits;privatelong timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;privatelong sequenceMask =-1L^(-1L<< sequenceBits);//记录产生时间毫秒数,判断是否是同1毫秒privatelong lastTimestamp =-1L;publiclonggetWorkerId(){return workerId;}publiclonggetDatacenterId(){return datacenterId;}publiclonggetTimestamp(){returnSystem.currentTimeMillis();}publicIdWorker(long workerId,long datacenterId,long sequence){// 检查机房id和机器id是否超过31 不能小于0if(workerId > maxWorkerId || workerId <0){thrownewIllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0",maxWorkerId));}if(datacenterId > maxDatacenterId || datacenterId <0){thrownewIllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0",maxDatacenterId));}this.workerId = workerId;this.datacenterId = datacenterId;this.sequence = sequence;}// 这个是核心方法,通过调用nextId()方法,让当前这台机器上的snowflake算法程序生成一个全局唯一的idpublicsynchronizedlongnextId(){// 这儿就是获取当前时间戳,单位是毫秒long timestamp =timeGen();if(timestamp < lastTimestamp){System.err.printf("clock is moving backwards. Rejecting requests until %d.", lastTimestamp);thrownewRuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds",
lastTimestamp - timestamp));}// 下面是说假设在同一个毫秒内,又发送了一个请求生成一个id// 这个时候就得把seqence序号给递增1,最多就是4096if(lastTimestamp == timestamp){// 这个意思是说一个毫秒内最多只能有4096个数字,无论你传递多少进来,//这个位运算保证始终就是在4096这个范围内,避免你自己传递个sequence超过了4096这个范围
sequence =(sequence +1)& sequenceMask;//当某一毫秒的时间,产生的id数 超过4095,系统会进入等待,直到下一毫秒,系统继续产生IDif(sequence ==0){
timestamp =tilNextMillis(lastTimestamp);}}else{
sequence =0;}// 这儿记录一下最近一次生成id的时间戳,单位是毫秒
lastTimestamp = timestamp;// 这儿就是最核心的二进制位运算操作,生成一个64bit的id// 先将当前时间戳左移,放到41 bit那儿;将机房id左移放到5 bit那儿;将机器id左移放到5 bit那儿;将序号放最后12 bit// 最后拼接起来成一个64 bit的二进制数字,转换成10进制就是个long型return((timestamp - twepoch)<< timestampLeftShift)|(datacenterId << datacenterIdShift)|(workerId << workerIdShift)| sequence;}/**
* 当某一毫秒的时间,产生的id数 超过4095,系统会进入等待,直到下一毫秒,系统继续产生ID
* @param lastTimestamp
* @return
*/privatelongtilNextMillis(long lastTimestamp){long timestamp =timeGen();while(timestamp <= lastTimestamp){
timestamp =timeGen();}return timestamp;}//获取当前时间戳privatelongtimeGen(){returnSystem.currentTimeMillis();}/**
* main 测试类
* @param args
*/publicstaticvoidmain(String[] args){System.out.println(1&4596);System.out.println(2&4596);System.out.println(6&4596);System.out.println(6&4596);System.out.println(6&4596);System.out.println(6&4596);// IdWorker worker = new IdWorker(1,1,1);// for (int i = 0; i < 22; i++) {// System.out.println(worker.nextId());// }}}