1、冒泡排序
算法思想:每次扫描待排序的元素,相邻元素满足排序条件,则交换,每一趟排序使最大(或最小)元素放置到末尾,经过n-1次扫描完成排序,最坏情况是扫描后交换,最好情况是元素本身有序,只需扫描,而不需要交换元素。
public class BubbleSort {
public static void bubbleSort(int [] arr){
for(int i=arr.length-1; i>0; i--){ //n-1趟冒泡
for(int j=0; j<i; j++){ //每趟冒泡交换相邻元素,找出最大值
if(arr[j] > arr[j+1]){
int temp = arr[j] ;
arr[j] = arr[j+1];
arr[j+1] = temp ;
}
}
}
}
public static void main(String[] args){
int [] arr = {2,1,6,3,5,4,7,9,8,10,0} ;
bubbleSort(arr) ;
for(int k=0; k<arr.length; k++){
System.out.print(arr[k] + " ") ;
}
}
}2、插入排序
算法思想:将待排序的元素分为"已排序"和"未排序"两种,每次从未排序的元素中选择一个插入到已排序的元素中。
public class InsertSort {
public static void insertSort(int [] arr){
for(int i=1; i<arr.length; i++){
int key = arr[i] ; //未排序的第一个元素
int j = i - 1 ; //已排序的最后一个元素的下标
while(j>=0 && arr[j] > key){
arr[j+1] = arr[j] ; //后移一位,空出插入位置
j -- ;
}
arr[j+1] = key ; //插入
}
}
public static void main(String[] args){
int [] arr = {2,1,4,3,6,7,5,0,10,9} ;
insertSort(arr) ;
for(int j=0; j<arr.length; j++){
System.out.print(arr[j] + " ") ;
}
}
}3、选择排序
算法思想:每次从未排序的元素中选择一个最小的,和未排序的首位元素进行交换,直至所有元素有序。
public class SelectSort {
public static void selectSort(int [] arr){
for(int i=0; i<arr.length; i++){
int ith = i ;
for(int j=i+1; j<arr.length; j++){
if(arr[ith] > arr[j]){
int temp = arr[ith];
arr[ith] = arr[j] ;
arr[j] = temp ;
}
}
}
}
public static void main(String[] args){
int [] arr = {3,2,1,4,6,5,8,9,7,10,0} ;
selectSort(arr) ;
for(int j=0; j<arr.length; j++){
System.out.print(arr[j] + " ") ;
}
}
}4、希尔排序
算法思想:一趟一个增量,用增量进行分组,组内进行插入排序,分组交错执行。
public class ShellSort {
public static void shellSort(int [] arr){
for(int interval = arr.length/2; interval > 0; interval=interval/2){//不断缩小增量
for(int j=interval; j < arr.length; j++){ //分组交替执行插入排序
int key = arr[j] ;
int k = j - interval ;
while(k>=0 && arr[k] > key){
arr[k+interval] = arr[k] ;
k -= interval ;
}
arr[k+interval] = key ; //插入
}
}
}
public static void main(String[] args){
int [] arr = {2,1,4,3,7,6,8,0,10,9} ;
shellSort(arr) ;
for(int i=0; i<arr.length; i++){
System.out.print(arr[i] + " ") ;
}
}
}5、快速排序
算法思想:分治的思想,选择一个元素作为主元,直至主元左侧元素都比主元小,主元右侧元素都比主元大,缩小数组范围,递归的进行快速排序。
public class QuickSort {
public static void swap(int [] arr, int left, int right){ //交换arr[left]和arr[right]的方法
int temp = arr[left] ;
arr[left] = arr[right] ;
arr[right] = temp ;
}
//划分的方法,每次划分将比采用双指针扫描,找出左侧比主元大的,找出右侧比主元小的,二者交换,返回主元的位置
public static int partition(int [] arr, int p, int r){
int pivot = arr[p] ; //初始化主元
int left = p + 1; //左侧扫描指针
int right = r ; //右侧扫描指针
while(left <= right){
while(left <= right && arr[left] <= pivot){
left ++ ;
}
while(left <= right && arr[right] >= pivot){
right -- ;
}
if(left < right){ //找到左侧比主元大的,右侧比主元小的,二者交换
swap(arr, left, right) ;
}
}
swap(arr, p, right) ; //将初始化的主元与划分后得到的主元交换
return right ;
}
public static void quickSort(int [] arr, int left, int right){
if(left < right){
int q = partition(arr, left, right) ; //每次划分得到主元,保证主元左侧元素小于主元,右侧元素大于主元
quickSort(arr, 0, q-1) ; //对主元左侧递归快速排序
quickSort(arr, q+1, right); //对主元右侧递归快速排序
}
}
public static void main(String[] args){
int [] arr = {2,1,3,7,6,9,4,5,0,9,10,8} ;
quickSort(arr, 0, arr.length-1) ;
for(int i=0; i<arr.length; i++){
System.out.print(arr[i] + " ") ;
}
}
}6、归并排序
算法思想:划分后,对左侧和右侧分别进行归并排序,再合并。合并借助辅助数组。
public class MergeSort {
public static void mergeSort(int [] arr, int p, int r){
if(p < r){
int mid = (p + r) >>> 1 ;
mergeSort(arr, 0, mid - 1) ;
mergeSort(arr, mid + 1, r) ;
merge(arr, p, r, mid) ;
}
}
public static void merge(int [] arr, int p, int r, int mid){
int [] helper = new int [arr.length] ;
for(int i=0; i<arr.length; i++){ //将数组元素值存放到辅助数组helper上
helper[i] = arr[i] ;
}
int left = p ;//左半部分头指针
int right = mid + 1 ; //右半部分头指针
int current = p ; //原数组头指针
while(left<=mid && right <= r){
if(helper[left] <= helper[right]){
arr[current++] = helper[left++] ;
}else{
arr[current++] = helper[right++] ;
}
}
while(left <= mid){ //左边指针未到头,需要填充到数组arr尾部,右侧指针未到头,不需要进行处理
arr[current ++] = helper[left++] ;
}
}
public static void main(String[] args){
int [] arr = {2,1,5,4,7,6,9,3,10,0} ;
mergeSort(arr, 0, arr.length - 1) ;
for(int j=0; j<arr.length; j++){
System.out.print(arr[j] + " ") ;
}
}
}7、堆排序
算法思想:先堆化,以n/2-1为根元素开始,不停调整堆,建立大根堆,再将堆顶元素与最后元素交换,缩小堆元素的范围,递归向下调整,直至最终有序。
public class HeapSort {
public static void maxHeap(int [] arr, int n){
for(int i = n/2-1; i>=0; i--){ //递归向下调整,建立大根堆
fixHeap(arr, i, n) ;
}
}
public static void fixHeap(int [] arr, int i, int n){ //i为根节点,n为堆中元素个数
int left = 2 * i + 1 ;
int right = 2 * i + 2 ;
int max = right ;
if(left >= n){ //左孩子越界,则右孩子必越界
return ;
}
if(right >= n && left < n){ //左孩子不越界,右孩子越界
max =left ;
}
if(right < n){ //右孩子不越界,左孩子不越界
if(arr[right] >= arr[left]){
max = right ;
}else{
max = left ;
}
}
if(arr[i] >= arr[max]){ //根节点元素比左右孩子元素都大,不调整
return ;
}else { //反之,选择左右孩子大的与根节点元素交换,递归向下调整
int temp = arr[max];
arr[max] = arr[i];
arr[i] = temp;
fixHeap(arr, max, n);
}
}
public static void heapSort(int [] arr, int n){
maxHeap(arr,n) ;//建立大根堆
for(int j=n-1; j>=0; j--){ //交换堆顶元素与最后一个元素,递归调整为大根堆
int temp = arr[0] ;
arr[0] = arr[j] ;
arr[j] = temp ;
fixHeap(arr, 0, j) ;
}
}
public static void main(String[] args){
int [] arr = {2,1,5,6,4,7,0,3,10,9,8} ;
heapSort(arr, arr.length) ;
for(int i=0; i<arr.length; i++){
System.out.print(arr[i] + " ") ;
}
}
}8、计数排序
算法思想:用辅助数组,对原数组中出现的数字进行计数,元素转下标,最后下标转元素。
public class CountingSort {
public static int max(int [] arr){ //求出数组中最大元素
int max = arr[0] ;
for(int i=1; i<arr.length; i++){
if(max < arr[i]){
max = arr[i] ;
}
}
return max ;
}
public static int min(int [] arr){ //求出数组中最小元素
int min = arr[0] ;
for(int i=1; i<arr.length; i++){
if(min > arr[i]){
min = arr[i] ;
}
}
return min ;
}
public static void countingSort(int [] arr){ //计数排序
int max = max(arr) ;
int min = min(arr) ;
int [] helper = new int [max - min + 1] ; //辅助数组
for(int i=0; i<arr.length; i++){ //计数
helper[arr[i] - min] ++ ;
}
int index = 0, j = 0 ;
while(j < arr.length){ //依次存放到原来数组
while(helper[index] > 0){
arr[j] = index - min ;
j ++ ;
helper[index] -- ;
}
index ++ ;
}
}
public static void main(String[] args){
int [] arr = {2,1,3,-1,3,6,0,10,9,8,7,4} ;
countingSort(arr) ;
for(int i=0; i<arr.length; i++){
System.out.print(arr[i] + " ") ;
}
}
}9、桶排序
算法思想:通过分配和收集的方式完成排序设计k个桶,编号0-k-1,将n个元素分配存到不同的桶中,桶内排序,然后遍历桶,从桶中取出即可。
public class BucketSort {
public static void bucketSort(int [] arr){
int max = Integer.MIN_VALUE ;
int min = Integer.MAX_VALUE ;
for(int i=0; i<arr.length; i++){ //找出数组中的最大元素和最小元素
max = (max <= arr[i]) ? arr[i] : max ;
min = (min >= arr[i]) ? arr[i] : min ;
}
//计算桶的数量
int bucketNum = (max - min) / arr.length + 1 ;
ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>() ;
for(int i=0; i<bucketNum; i++){
bucketArr.add(new ArrayList<>()) ;
}
//将元素入桶
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(int j=0; j<bucketArr.size(); j++){
for(int k=0; k<bucketArr.get(j).size(); k++){
arr[index++] = bucketArr.get(j).get(k) ;
}
}
}
public static void main(String[] args){
int [] arr = {1,5,2,9,3,0,4,10,8,7,6,-1} ;
bucketSort(arr) ;
for(int i=0; i<arr.length; i++){
System.out.print(arr[i] + " ") ;
}
}
}10、基数排序
算法思想:按照位数进行分配和回收,n次分配回收后,元素有序。
public class RadixSort {
private static ArrayList [] bucket = new ArrayList [10] ; //定义10个桶
static {
for(int i=0; i<bucket.length; i++){
//为每个桶分配对象
bucket[i] = new ArrayList() ;
}
}
public static int max(int [] arr){ //找出数组元素的最大值
int max = arr[0] ;
for(int i=1; i<arr.length; i++){
if(arr[i] > max){
max = arr[i] ;
}
}
return max ;
}
public static void putInBucket(int data, int digit){ //入桶
switch(digit){ //根据基数位判断进入哪个桶
case 0 : bucket[0].add(data) ; break ;
case 1 : bucket[1].add(data) ; break ;
case 2 : bucket[2].add(data) ; break ;
case 3 : bucket[3].add(data) ; break ;
case 4 : bucket[4].add(data) ; break ;
case 5 : bucket[5].add(data) ; break ;
case 6 : bucket[6].add(data) ; break ;
case 7 : bucket[7].add(data) ; break ;
case 8 : bucket[8].add(data) ; break ;
case 9 : bucket[9].add(data) ; break ;
default: break ;
}
}
public static Integer getDigitOn(int elements, int d){ //取出数字的第d位
String s = String.valueOf(elements) ;
return Integer.parseInt(s.charAt(d-1)+"") ;
}
//将数组按照d个位来分配和收集
public static void sort(int [] arr, int d){
for(int i=0; i<arr.length; i++){ //入桶
putInBucket(arr[i], getDigitOn(arr[i], d)) ;
}
//出桶
int index = 0 ;
for(int j=0; j<bucket.length; j++){
for(Object m : bucket[j]){
arr[index++] = (Integer)m ;
}
}
clearAll() ;
}
public static void clearAll(){ //清空桶
for(ArrayList b : bucket){
b.clear() ;
}
}
public static void radixSort(int [] arr){
int d = 1 ; //入桶时候初始化位数
int max = max(arr) ; //数组中最大元素
int length = 1 ; //最大数据的位数
while(max / 10 != 0){
length ++ ;
max /= 10 ;
}
while(length >= d){
sort(arr, d++) ; //递归的进行分配和收集
}
}
public static void main(String[] args){
int [] arr = {2,1,5,4,0,7,9,8,6} ;
radixSort(arr) ;
for(int i=0; i<arr.length; i++){
System.out.print(arr[i] + " ") ;
}
}
}

0条评论
点击登录参与评论