八大排序(Java)

1.冒泡排序

public static void bubul(int arr[]){
       for(int i = 0;i<arr.length;i++){
           for(int j = 0;j<arr.length-1-i;j++){
                   //最后i个元素顺序不用改变
                   if(arr[j] > arr[j+1]){
                       int t;
                       t = arr[j];
                       arr[j] = arr[j+1];
                       arr[j+1] = t;
                   }
               }
             }
}

第二层循环将数组从头开始两两比较,交换最后得到一个最大值在数组最后,再在第一层循环里循环n次。

2.堆排序

//维护堆的性质
	public static void heapify(int[] arr,int n,int i) {
		int largest = i;
		int lson = i*2 + 1;
		int rson = i*2 + 2;
		if((lson < n)&&(arr[largest]<arr[lson])) {
			largest = lson;
		}
        //可能lson和rson的值会大于n因此if里要先判断
		if((rson < n)&&(arr[largest]<arr[rson])) {
			largest = rson;
		}
        
		if(largest != i) {
			int temp = arr[largest];
			arr[largest] = arr[i];
			arr[i] = temp;
            //当位置改变时其后面堆的性质可能也会发生改变
			heapify(arr,n,largest);
		}
		
	}	
	//堆排序的入口
	public static void heap_sort(int[] arr,int n) {
       //从最后一个父节点开始向上维护堆的性质
		for(int i = n/2-1;i>=0;i--) {
			heapify(arr,n,i);
		}
       //将堆顶元素和堆底元素交换,将最大值放在数组最后,并从堆顶开始维护堆的性质
		for(int i = n-1;i>=0;i--) {
			int demo = arr[0];
			arr[0] = arr[i];
			arr[i] = demo;
			heapify(arr,i,0);
		}
	}

分两步,其一建立一个函数用来维护堆的性质,然后开始建堆,将最大值放在数组最后。

3.快排

public static void sort(int arr[],int left,int right) {	
		 //递归出口
		if(left >= right) {
			return;
		}
		//定义变量保存基准数
		int base = arr[left];		
		//定义i和j的游标
		int i = left;
		int j = right;	
		while(i != j) {
			//j从后往前找比基准数小的,找到后停下
			while(arr[j] >= base&&i<j) {
				j--;
			}
			//i从前往后找比基准数大的,找到后停下
			while(arr[i] <= base&&i<j) {
				i++;
			}
			//i和j交换
			int temp = arr[i];
			arr[i] = arr[j];
			arr[j] = temp;			
		}
		//i和j相遇后基准数和相遇位置数据进行交换
		
		arr[left] = arr[i];
		arr[i] = base;		
		//拆分左边
		sort(arr,left,i-1);
		//拆分右边
		sort(arr,i+1,right);
	} 

快排要以第一个元素为基准数,分成左右两波比基准数小和大,最后将i和j相等位置的数据和基准数交换,之后不断递归新基准数的左侧和右侧。

 4.选择排序

public static void sort(int[] arr) {
		for(int i = 0;i<arr.length;i++) {
			int min = arr[i];//记录最小值
			int minIndex = i;//记录最小值下标
			for(int j = i+1;j<arr.length;j++) {
				if(arr[j]<min) {
					min = arr[j];
					minIndex = j;
				}
			}
			//最小值和待排序数组和第一个进行交换
			arr[minIndex] = arr[i];
			arr[i] = min;
		}
	}

}

将第一个元素当作最小值,遍历之后的元素当找到最小的值后将其与之交换,之后不断重复。

 5.插入排序

public static void sort(int[] arr) {
		for(int i = 1;i<arr.length;i++) {
			for(int j = i-1;j>=0;j--) {
				if(arr[j]>arr[j+1]) {
					int temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}else {
					break;
				}
			}
		} 
	}

}

将每个插入元素都与前面排好序的数组进行比较插入。(但越小的数在后面移动的越多,改良希尔排序)。

 6.希尔排序

public static void sort(int[] arr) {
		for(int grp = arr.length/2;grp>=1;grp/=2) {
			for(int i = grp;i<arr.length;i++) {
				for(int j = i-grp;j>=0;j-=grp) {
					if(arr[j+grp]<arr[j]) {
						int temp = arr[j];
						arr[j] = arr[j+grp];
						arr[j+grp] = temp;
					}else {
						break;
					}
				}
			}
		}
	}

将数组不断按照组长的一半(一半的一半....)为间隔进行分组,每组进行插入排序。

7.基数排序

适用于数据量远远大于每个数据本身

public static void sort(int[] arr) {	
		//找数组当中最大值
		int max = arr[0];
		for(int j = 0;j<arr.length;j++) {
			if(arr[j]>max) {
				max = arr[j];
			}
		}
		//获取最大值的位数
		int maxLength = (max+"").length();
		//定义桶
		int[][] bucket = new int[10][arr.length];
		//定义桶记录工具
		int[] bucketCounts = new int[10];		
		int n = 1;		
		for(int h = 0;h<maxLength;h++) {
		//将输入放入桶内
		for(int i = 0;i<arr.length;i++) {
			//放到那个桶
			int element = arr[i]/n%10;//获取个位数值 element代表个位或十位或百位数值,也代表要放入那号桶
			//读取桶记录工具,确定放入桶哪个位置
			int count = bucketCounts[element];
			//数据放入
			bucket[element][count] = arr[i];
			//桶记录+1
			bucketCounts[element]++;
		}		
		//数据取出
		//遍历数组
		int index = 0;
		//遍历桶记录
		for(int k = 0;k<bucketCounts.length;k++) {
			if(bucketCounts[k]!=0) {
				for(int l = 0;l<bucketCounts[k];l++) {
					arr[index] = bucket[k][l];
					index++;
				}
			}
			bucketCounts[k] = 0;
		}
	     n*=10;
		}
	}

 8.归并排序

//拆分
	public static void split(int[] arr,int left,int right) {
		if(left == right) {
			return;
		}
		int i = (left+right)/2;
		//向左递归
		split(arr,left,i);
		//向右递归
		split(arr,i+1,right);
		//合并
		merge(arr,left,i,right);		
	}
	//合并
	public static void merge(int[] arr,int left,int mid,int right) {
		int s1 = left;
		int s2 = mid+1;
		//临时数组
		int temp[] = new int[right-left+1];
		//临时数组下标
		int index = 0;		
		while(s1<=mid&&s2<=right) {
			if(arr[s1]<arr[s2]) {
				temp[index] = arr[s1];
				index++;
				s1++;				
			}else {
				temp[index] = arr[s2];
				index++;
				s2++;
			}
		}
		//判断s1当中是否有数据
		while(s1<=mid) {
			temp[index] = arr[s1];
			index++;
			s1++;			
		}
		//判断s2当中是否有数据
		while(s2<=right) {
			temp[index] = arr[s2];
			index++;
			s2++;			
		}
		//临时数组当中的数值放回原数组
		for(int j = 0;j<temp.length;j++) {
			arr[left+j] = temp[j];
		}
	}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值