由于算法非同一时间完成,所以部分未采用SwapClass
public class SwapClass {
public static void swap(int[] arr,int i,int j){
int tem=arr[i];
arr[i]=arr[j];
arr[j]=tem;
}
}
1、折半查找:
又叫二分查找,要求待查找序列有序。取中间位置的值与待查关键字比较,如果中间位置的数大,则向左侧数据重复此过程,否则向右侧执行此过程,如果中间值等于待查找关键字则返回,否则查找失败。
public class Binsearch {
// 递归法
public int search(int[] arr,int a,int lo,int hi ){
int mid=(lo+hi)/2;
if(lo>hi) return -1;
if(arr[mid]==a) return mid;
else if(arr[mid]>a)
{
return search(arr,a,lo,mid-1);
} else if (arr[mid] < a) {
return search(arr,a,mid+1,hi);
}
else {
System.out.println("查询失败");
return -1;
}
}
}
public class MainClass {
public static void main(String[] args) {
int[] arr={1,2,3,4,5,6,7,8};
int lo=0;
int hi=arr.length-1;
Binsearch binsearch = new Binsearch();
int search = binsearch.search(arr, 3, lo, hi);
if (search < 0) {
System.out.println("不在序列中");
}
else{
System.out.println("查找成功"+search);
}
}
}
2、冒泡排序:
比较前后两个数据,如果前面数据大于后面的数据就交换。对数组的第n-1个数据遍历一趟后,数据长度减一,继续排序。
public class BubbleSearch {
public int[] search(int[] arr){
int n=arr.length;
for(int i=0;i<n;i++)
for(int j=1;j<n-i;j++)
{
if(arr[j]<arr[j-1]){
int t;
t=arr[j];
arr[j]=arr[j-1];
arr[j-1]=t;
}
}
return arr;
}
}
int[] arr={5,4,6,8,2,1,3,5,4};
System.out.println("排序前:");
for (int i : arr) {
System.out.print(i);
}
BubbleSearch bubbleSearch = new BubbleSearch();
int[] search = bubbleSearch.search(arr);
System.out.println("排序后:");
for (int i : search) {
System.out.print(i);
}
3、直接插入排序:
将无序区中的数据按序插入已排序区。
public class InsertSort {
public int[] sort(int[] arr){
for(int i=1;i<arr.length;i++)
{
int insertVal=arr[i];
int index=i-1;
while(index>=0&&arr[index]>insertVal)
{
arr[index+1]=arr[index];
arr[index]=insertVal;
index--;
}
}
return arr;
}
}
int[] arr={6,5,4,3,2,1};
System.out.println("排序之前:");
for (int i : arr) {
System.out.print(i);
}
InsertSort insertSort = new InsertSort();
int[] sort = insertSort.sort(arr);
System.out.println("排序之后:");
for (int i : sort) {
System.out.print(i);
}
4、快速排序法:
从序列中选择一个基准值,将比基准值小的放在左侧,将比序列值大的放在右侧。
int[] arr={9,6,4,3,4};
System.out.println("排序前");
for (int i : arr) {
System.out.print(i);
}
QuickSort quickSort = new QuickSort();
quickSort.sort(arr,0,arr.length-1);
System.out.println("排序后");
for (int i : arr) {
System.out.print(i);
}
public class QuickSort {
public void sort(int[] arr,int lo,int hi){
int start=lo;
int end=hi;
int key=arr[start];
while(start<end){
while(start<end&&key<=arr[end]){
end--;
}
if(start!=end&&key>arr[end])
{
arr[start]=arr[end];
start++;
}
while(start<end&&key>=arr[start])
{
start++;
}
if(start!=end&&key<arr[start]){
arr[end]=arr[start];
end--;
}
if (start == end) {
arr[start]=key;
}
}
if(start>lo)
{
sort(arr, lo, start-1);
}
if(end<hi){
sort(arr, end+1, hi);
}
}
}
5、希尔排序:
插入排序的一种,设置一个增量按照增量将序列分割为若干子序列,对每个子序列进行直接插入排序。减小增量循环以上操作直到增量为1。
public class ShellSort {
public void sort(int[] arr) {
int dk = arr.length / 2;
while (dk >= 1) {
insertSort(arr, dk);
dk = dk / 2;
}
}
private void insertSort(int[] array, int dt) {
for (int i = dt; i < array.length; i++) {
int insert = array[i];
for (int j = i - dt; j >= 0; j = j - dt) {
if (array[j] > insert) {
array[j + dt] = array[j];
array[j] = insert;
}
}
}
}
}
System.out.println("排序前");
for (int i : arr) {
System.out.print(i);
}
ShellSort shellSort = new ShellSort();
shellSort.sort(arr);
System.out.println("排序后");
for (int i : arr) {
System.out.print(i);
}
6、归并排序:
递归划分,迭代合并。
归并排序
System.out.println("排序前");
for (int i : arr) {
System.out.print(i);
}
MergeSort mergeSort = new MergeSort();
mergeSort.mergeSortFun(arr);
System.out.print("排序后");
for (int i : arr) {
System.out.print(i);
}
public class MergeSort {
public void mergeSortFun(int[] arr){
sort(arr,0,arr.length-1);
}
private void sort(int[] arr,int left,int right){
int center=(left+right)/2;
if(left<right)
{
sort(arr,left,center);
sort(arr,center+1,right);
merge(arr,left,center,right);
}
}
private void merge(int[] arr,int le,int mid,int ri){
int[] tmpArr=new int[arr.length];
int l_pos=le;
int r_pos=mid+1;
int tmp=le;
int third=le;
while(l_pos<=mid&&r_pos<=ri){
if(arr[l_pos]<=arr[r_pos])
{
tmpArr[tmp++]=arr[l_pos++];
}
if(arr[l_pos]>arr[r_pos])
{
tmpArr[tmp++]=arr[r_pos++];
}
}
while (l_pos<=mid){
tmpArr[tmp++]=arr[l_pos++];
}
while (r_pos<=ri){
tmpArr[tmp++]=arr[r_pos++];
}
while(third<=ri)
{
arr[third]=tmpArr[third++];
}
}
}
7、桶排序:
将序列分成若干份序列分布在桶中,将每个桶排序,最后合并。
System.out.println("排序前");
for (int i : arr) {
System.out.print(i);
}
BucketSort bucketSort = new BucketSort();
bucketSort.Sort(arr,3);
System.out.println("排序后");
for (int i : arr) {
System.out.print(i);
}
public class BucketSort {
/**
*
* @param arr 待排序序列
* @param bucketSize 每个桶数据个数
*/
public void Sort(int[] arr,int bucketSize){
// 找出序列中最大值和最小值
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)/bucketSize+1;
// 创建桶
int[][] buckets=new int[bucketNum][0];
for(int i=0;i<arr.length;i++){
int index=(arr[i]-min)/bucketSize;
buckets[index]=arrAppend(buckets[index],arr[i]);
}
// 对桶排序
int arrIndex=0;
for (int[] bucket : buckets) {
InsertSort insertSort = new InsertSort();
insertSort.sort(bucket);
for (int i : bucket) {
arr[arrIndex++]=i;
}
}
}
private static int[] arrAppend(int[] arr,int val){
int[] ar = Arrays.copyOf(arr, arr.length + 1);
ar[ar.length-1]=val;
return ar;
}
}
8、基数排序:
根据基数将数据从低位到高位依次排序,基数一般为进制数。
System.out.println("排序前");
for (int i : arr) {
System.out.print(i);
}
RadixSort radixSort = new RadixSort();
radixSort.sort(arr);
System.out.println("排序后");
for (int i : arr) {
System.out.print(i);
}
public class RadixSort {
public void sort(int[] arr) {
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (max < arr[i]) {
max = arr[i];
}
}
// 根据数组的最大值求位数
int time = 0;
while (max > 0) {
max /= 10;
time++;
}
List<ArrayList> queue = new ArrayList<>();
for (int i = 0; i < 10; i++) {
ArrayList<Integer> queue1 = new ArrayList<>();
queue.add(queue1);
}
for (int i = 0; i < time; i++) {
// 为容器中设置数据
for (int j = 0; j < arr.length; j++) {
int index = arr[j] % (int) Math.pow(10, i + 1) / (int) Math.pow(10, i);
ArrayList<Integer> queue2 = queue.get(index);
queue2.add(arr[j]);
queue.set(index, queue2);
}
// 将容器中的数据放入arr
int arrIndex = 0;
for (int k = 0; k < 10; k++) {
while (queue.get(k).size() > 0) {
ArrayList<Integer> queue3 = queue.get(k);
arr[arrIndex++] = queue3.get(0);
queue3.remove(0);
}
}
}
}
}
9、简单选择排序:
从无序区选择最小的关键字,放入有序区最后。
简单选择排序
System.out.println("排序前");
for (int i : arr) {
System.out.print(i);
}
System.out.println("\n");
SelectSort selectSort = new SelectSort();
selectSort.sort(arr);
System.out.println("排序后");
for (int i : arr) {
System.out.print(i);
}
public class SwapClass {
public static void swap(int[] arr,int i,int j){
int tem=arr[i];
arr[i]=arr[j];
arr[j]=tem;
}
}
public class SelectSort {
public void sort(int[] arr){
for(int j=0;j<arr.length-1;j++){
int minPos=j;
for(int i=j+1;i<arr.length;i++){
if(arr[i]<=arr[minPos]){
minPos=i;
}
}
if(minPos==j){
continue;
}
SwapClass.swap(arr,j,minPos);
}
}
}
10、堆排序:
将待排序根据索引构建为完全二叉树,索引顺序为从左到右,从上到下,将完全二叉树排序为大顶堆,将堆顶元素与堆尾元素交换,视作堆尾为不在结构中,无序区减少,重复以上操作最终根据索引列出序列。
堆排序根据大,小顶堆的特性,将序列选择排序,根据序列的排序需求选择每次需要排序为大顶堆还是小顶堆。
堆排序
int[] arr={5,4,3,2,1};
System.out.println("排序前");
for (int i : arr) {
System.out.print(i);
}
HeapSort heapSort = new HeapSort();
heapSort.sort(arr,arr.length);
System.out.println("\n");
System.out.println("排序后");
for (int i : arr) {
System.out.print(i);
}
public class HeapSort {
/**
*
* @param arr 待排序列
* @param l 序列长度
*/
// 求i节点的父节点,为(i-1)/2
// 序列的总长为l,则堆的首个非叶子节点为((n-1)-1)/2,为n/2-1
public void sort(int[] arr,int l){
// 建堆
for(int i=l/2-1;i>=0;i--){
heapify(arr,l,i);
}
// 排序
for (int i=l-1;i>0;i--) {
SwapClass.swap(arr,i,0);
heapify(arr,i,0);
}
}
// 维护堆,使堆元素保持为大顶堆状态
// 根节点的左节点为i*2+1,右节点为i*2+2
/**
*
* @param arr 待排序列
* @param l 序列长度
* @param i 当前节点索引
*/
public void heapify(int[] arr,int l,int i){
int largest=i;
int l_nod=i*2+1;
int r_nod=i*2+2;
if(l_nod<l&&arr[l_nod]>arr[largest])
{
largest=l_nod;
}
if(r_nod<l&&arr[r_nod]>arr[largest])
{
largest=r_nod;
}
if(largest!=i){
SwapClass.swap(arr,largest,i);
heapify(arr,l,largest);
}
}
}