八种排序算法总结

1.冒泡排序演示动画:

2.堆排序演示动画:https://www.bilibili.com/video/av12667435


3.选择排序演示动画:

4.插入排序演示动画:

5.希尔排序演示动画:

6.归并排序演示动画:

7.快速排序演示动画:

8.基数排序演示动画:

package Connection;

import java.util.Scanner;

public class SortMeans {
	private static Scanner cin;
	
	public void bubble_sort(int arr[]){  // 1.冒泡排序 --- 像气泡一样,小的上浮,大的下沉
	    int temp;
	    for(int i=0;i<arr.length;i++)	
	    	for(int j=arr.length-1;j>i;j--) {	//每循环一次都会将最小元素排到最前面,所以每次进行一次循环,下一次循环的数组长度都需要减小1
	    		if(arr[j]<arr[j-1]) {//如果后面元素小于前面元素,则两元素交换位置
	    			temp = arr[j];
	    			arr[j] = arr[j-1];
	    			arr[j-1] = temp;
	    		}
	    	}
	}

	public void select_sort(int arr[]){  // 2.选择排序 --- 每次循环选出最小的值排在最前面
		int min;
		for(int i=0;i<arr.length-1;i++) {	//每进行一次循环都会将最小元素选出来,然后将此元素与第a[j]个元素交换位置,使得a[j]元素比j后面的所有元素的值都小
			min = i;
			for(int j=i+1;j<arr.length;j++) {
				if(arr[j]<arr[min]) {
					min = j;
				}
				if(i != min) {
					int temp = arr[i];
					arr[i] = arr[min];
					arr[min] = temp;
				}
			}
			
		}
	}

	public void shell_sort(int arr[]){   // 3.希尔排序,插入排序的改进
		int index = arr.length/2;	//改进了插入排序每插入一个元素都需要移动后面所有元素的位置不能够大步移动的缺点,首个突破了O(n^2)的时间复杂度
		while(index >= 1) {		
		for(int i=index;i<arr.length;i++) {
			for(int j=i-index;j>=0;j=j-index) {
				if(arr[j]>arr[j+index]) {
					int temp = arr[j];
					arr[j] = arr[j+index];
					arr[j+index] = temp;
				}
			}
		}
		index /= 2;
		}
	}

	void merge_sort(int arr[],int left,int right) { // 4.归并排序
		int[] temp = new int[right - left + 1];	//与73行相对应
		if(left < right) {
		merge_sort(arr,left,(left + right)/2);//排序左半部分
		merge_sort(arr,(left + right)/2 + 1,right);//排序右半部分
		merge(arr,left,(left + right)/2,right,temp);//合并排序
		}
		else return;

	}
	
	public void merge(int arr[],int left,int mid,int right,int temp[]){
		int i = left,j = mid + 1;
		int k = 0;
		//将一个数组拆分成两个数组,将这两个数组元素按顺序依次比较,将较小的取出来放到temp数组中
		while(i <= mid && j <= right) {
			if(arr[i] < arr[j]) {
				temp[k++] = arr[i++];
			}
			else 
				temp[k++] = arr[j++];	
		}
		//如果left全取尽了right仍有剩余或right全取尽了left仍有剩余,则将未取尽的数组直接copy到temp数组中
		while(i <= mid) {
			temp[k++] = arr[i++];
		}
		while(j <= right) {
			temp[k++] = arr[j++];
		}
		for(int p = 0;p < temp.length;p++)
			arr[left + p] = temp[p];
		
	}

	public void quick_sort(int arr[] , int left , int right){   //5.快速排序,分治思想
		if(left >= right)
			return ;
		int pivot = arr[left];
		int i = left , j = right;
		while(i != j) {		//一定要先循环j
			while(arr[j] >= pivot && i < j) {
				j--;
			}
			while(arr[i] <= pivot && i < j) {
				i++;
			}
		int temp = arr[i];
			arr[i] = arr[j];
			arr[j] = temp;
		}
		arr[left] = arr[i];
		arr[i] = pivot;
		quick_sort(arr, left, i - 1);
		quick_sort(arr, i + 1, right);
	}
	
	public void heap_sort(int arr[],int lengthIndex){    // 6.堆排序
		BuildHeap(arr,lengthIndex);//构建堆,且时刻保持堆顶元素为最大值
		int temp = arr[0];	//交换堆顶元素与队尾元素,保证队尾元素是最大值
		arr[0] = arr[lengthIndex];
		arr[lengthIndex] = temp;
		if(lengthIndex > 0) //如果堆大于0,则进行递归,堆减小1
			heap_sort(arr, lengthIndex-1);
	}
	
	public void BuildHeap(int arr[],int lengthIndex){	//构建一个时刻保持堆顶元素最大的大堆顶
		int temp;
		for(int i=lengthIndex/2;i>=0;i--) {	//先从左子树比较
			if((2*i+1)<=lengthIndex &&arr[i]<arr[2*i+1]) {
				temp = arr[i];
				arr[i] = arr[2*i+1];
				arr[2*i+1] = temp;
			}
			if((2*i+2)<=lengthIndex &&arr[i]<arr[2*i+2]) {	//后从右子树比较
				temp = arr[i];
				arr[i] = arr[2*i+2];
				arr[2*i+2] = temp;
			}		
		}
	}


	public void insert_sort(int arr[]){  //7.插入排序,类似整理扑克牌
		
		for(int i=1;i<arr.length;i++) {	 //假定下标为0的已经排好序,所以从下标为1开始排序
			int j = i;
			int flag = arr[j];
			while(j>0 && flag<arr[j-1]) {	//如果代插入的数比前面的数小,则将前面的数向后挪一个位置,留给代插入的flag.
				arr[j] = arr[j-1];
				j--;
			}
			arr[j] = flag;
		}
		
	}

	   public static void radix_sort(int[] data,int max){	// 3.基数排序 max为所有数字中最大的位数
	        int[][] bucket = new int[10][data.length];	//这是二维数组组成的桶
	        int[] countor = new int[10];	//此数组用来记录0-9每个桶中的数字个数,计数器
	        int k = 0;	//k用来记录原数组的元素位置
	        int n = 1;	//用来计算不同位数的相应位置上的值
	        int digit = 1;
	        while(digit<max){
	            for(int i=0;i<data.length;i++){
	                int index = ((data[i]/n)%10);	//得出相应位置(如个位、十位)上的数字
	                bucket[index][countor[index]] = data[i];	//取出来放到桶里
	                countor[index]++;	//相应的桶中的容量加1
	            }
	            for(int i=0;i<10;i++){	//从桶中依次收集数据
	                if(countor[i]!=0){	//各个桶不为空时收集
	                    for(int j=0;j<countor[i];j++){
	                        data[k] = bucket[i][j];
	                        k++;
	                    }
	                }
	                countor[i] = 0;	//相应桶中的数据已经回收完,相应计数器归0
	            }
	            digit++;	//位数向右移动
	            n*=10;
	            k = 0;  
	        }
	    }


	public static void main(String[] args){
		cin = new Scanner(System.in);
	    System.out.println("输入要排序的个数");
	    int n = cin.nextInt();
	    int[] arr = new int[n];
		System.out.println("请输入你要排序的数组元素");
	    for(int i=0;i<n;i++)
	    {
	    	arr[i] = cin.nextInt();
	    }
	    System.out.println("输入你要选择的排序方式");
	    System.out.println("1.冒泡排序--2.选择排序--3.基数排序--4.堆排序--5.插入排序--6.归并排序--7.快速排序.--8.希尔排序--");
	    n = cin.nextInt();
	    System.out.print("排序前: ");
	    for(int i=0;i<arr.length;i++) {
	    	System.out.print(arr[i]+" ");
	    }
	    switch(n){
	        case 1:new SortMeans().bubble_sort(arr);;break;
	        case 2:new SortMeans().select_sort(arr);;break;
	        case 3:new SortMeans().radix_sort(arr,arr.length);;break;
	        case 4:new SortMeans().heap_sort(arr,arr.length-1);;break;
	        case 5:new SortMeans().insert_sort(arr);;break;
	        case 6:new SortMeans().merge_sort(arr,0,arr.length-1);;break;
	        case 7:new SortMeans().quick_sort(arr,0,arr.length-1);;break;
	        case 8:new SortMeans().shell_sort(arr);;;break;
	    }
    	System.out.print("\n排序后: ");
	    for(int i=0;i<arr.length;i++)
	    	System.out.print(arr[i]+" ");
	}
}

动画出处:https://blog.csdn.net/xiaoxiaojie12321/article/details/81380834

猜你喜欢

转载自blog.csdn.net/sinat_41721615/article/details/88199328