数据结构各种排序java实现个人总结

1、快速排序

package algorithm;

import java.util.Random;

/** 
 *  快速排序: 
 *          取第一个数 a 作为基准元素,将数组分成三部分,比a小的元素放到一个数组里面,比a大的放到一个数组里面,再分别对这两个数组进行快排 
 *          时间复杂度:O(nlogn) 
 *          不稳定 
 *  随机快排: 
 *          随机取一个元素作为基准元素,避免了极端的情况(比如其他元素都比第一个元素大或者小,最极端的情况会变成选择排序,复杂度为O(n^2)) 
 *          时间复杂度:O(nlogn) 
 *  以下是基于随机快排实现 
 */  
public class QuickSort {

	static int sum = 0;  
	static int[] arr = {4,5,26,85,46,19,52,6,37,88,44,8,9,3,22,12,21,23,32,50};

	public static void main(String[] args) {
		for (int a : arr) {
			System.out.print(a+"、");
		}
		quickSort(0,arr.length-1);
	}

	private static void quickSort(int left, int right) {
		if(left < right){
			int pIndex = partition(left,right);		//对数组进行划分,并返回划分的下标 
			System.out.println("\n第"+(++sum)+"轮排序后");
			for (int a : arr) {
				System.out.print(a+"、");
			}
			quickSort(left,pIndex);
			quickSort(pIndex+1,right);
		}
	}

	private static int partition(int left, int right) {
		int baseLine = new Random().nextInt(right-left)+left;
		System.out.print("\n随机生成的节点:"+baseLine);
		int baseValue = arr[baseLine];
		while(true){
			while(arr[left] < baseValue){
				left++;
			}
			while(arr[right] > baseValue){
				right--;
			}
			if(left >= right){
				break;
			}
			System.out.print("\n两个数交换,左:"+left+"右:"+right);
			swap(left,right);
		}
		return left;
	}

	//交换
	private static void swap(int left, int right) {
		int temp = arr[left];
		arr[left] = arr[right];
		arr[right] = temp;
	}
}
package algorithm;
/**
 * 特点:高效,时间复杂度为nlogn。
 * 采用分治法的思想:首先设置一个轴值pivot,然后以这个轴值为划分基准将待排序序列分成比pivot大和比pivot小的两部分,
 * 接下来对划分完的子序列进行快排直到子序列为一个元素为止。
 * @author change
 *
 */
public class FastSort {
	public static void main(String[] args) {
		int[] array = { 37, 47, 23, 100, 19, 56, 56, 99, 9 };
		FastSort fs = new FastSort();
		fs.quickSort(array,0,array.length-1);
		for (int a : array) {
			System.out.print(a+",");
		}
	}
	public void quickSort(int[] array,int low,int high){
		int pivot,p_pos,i,t;
		if(low<high){
			p_pos = low;
			pivot = array[p_pos];
			for (i = low+1; i <= high; i++) {
				if(array[i]<pivot){
					p_pos++;
					t = array[p_pos];
					array[p_pos] = array[i];
                    array[i] = t;
				}
			}
			t = array[low];
			array[low] = array[p_pos];
			array[p_pos] = t;
			//分而治之  递归
			quickSort(array, low, p_pos - 1);// 排序左半部分
            quickSort(array, p_pos + 1, high);// 排序右半部分
		}
	}
}

2、插入排序

package algorithm;
/**
 * 特点:效率低,容易实现。
 * 思想:将数组分为两部分,将后部分元素逐一与前部分元素比较,如果当前元素array[i]小,就替换。找到合理位置插入array[i]
 * @author change
 *
 */
public class InsertionSort {
	public static void main(String[] args) {
		int array[] = {57,68,59,52};
		int i,j,temp = 0;
		for (i = 0; i < array.length; i++) {
			temp = array[i];
			for (j = i-1; j >=0 && temp < array[j]; j--) {
				array[j+1] = array[j];
			}
			array[j+1] = temp;
		}
		for (int k : array) {
			System.out.print(k+",");
		}
	}
}

3、直接插入排序

package algorithm;
/**
 * 直接插入排序
 * 每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的字序列的合适位置(从后向前找到合适位置后),直到全部插入排序完为止。 
 * @author change
 * 分析
 * 直接插入排序是稳定的排序。
 * 文件初态不同时,直接插入排序所耗费的时间有很大差异。
 * 若文件初态为正序,则每个待插入的记录只需要比较一次就能够找到合适的位置插入,故算法的时间复杂度为O(n),这是最好的情况。
 * 若初态为反序,则第i个待插入记录需要比较i+1次才能找到合适位置插入,故时间复杂度为O(n2),这是最坏的情况。
 * 直接插入排序的平均时间复杂度为O(n2)。而且还要对数组中的数字进行逐个移位,所以性能比较差。
 */
public class StraightInsertionSort {

	static int[] arr = {57,68,59,52,12,10,4,1};

	public static void main(String[] args) {
		for (int i = 1; i < arr.length; i++) {
			for (int j = 0; j < i; j++) {
				if(arr[j]>arr[i]){
					int temp = arr[i];
					arr[i] = arr[j];
					arr[j] = temp;
				}
			}
		}
		for (int a : arr) {
			System.out.print(a+"、");
		}
	}
}

4、二分法插入排序

package algorithm;

import java.util.Scanner;

/**
 * 二分法插入排序的思想和直接插入一样,只是找合适的插入位置的方式不同,这里是按二分法找到合适的位置,可以减少比较的次数。
 * @author change
 * 直接插入排序算法,在排序数据量比较大的时候,二分插入排序的速度就要远远高于直接插入排序,那么二分插入排序算法的思想是什么呢?
 * 二分插入排序通过从第二个数开始将需要排序的数分为两个部分,左边部分有序,右边部分无序,
 * 然后从右边部分第一个数开始,一个一个插入前面有序部分,与直接插入排序唯一不同的是:二分插入排序会先找出左边有序部分的中间值,然后与需要插入的值比较,
 * 所以在插入之前,就只需要与左边有序部分的一半值进行比较。因此,在数据量比较大的时候,二分插入排序算法就更加高效,速度更快。
 */
public class BinarySort {
	
	static int[] arr = {57,68,59,52,12,10,4,1};
	
	//二分插入算法  
    public void binaryInsertSort(int[] str){  
        for (int i = 1; i < str.length; i++) {  
            if (str[i]<str[i-1]) {  
                int temp = str[i];        //定义temp存储所要插入的数  
                int left = 0;             //最左边的数,从str[0]开始  
                int right = i-1;              //最右边位,所要插入那个数的前一位  
                while(left<=right){  
                    int mid = (left+right)/2;   //mid中间位  
                    if (str[mid]<temp) {     //中间位与str[i]比较  
                        left = left + 1;              
                    }else {                     //通过if语句找到应该插入的位置str[left]  
                        right = right - 1;  
                    }  
                }  
                for (int j = i; j>left; j--) {   //将str[left]->str[i-1]的数都往后移一位  
                    str[j]=str[j-1];  
                }  
                str[left]=temp;      //最后将str[i]插入str[left]  
            }  
        }  
    }  
    //主函数  
    public static void main(String[] args){  
        Scanner scanner = new Scanner(System.in);  
        System.out.println("请输入一个数组:");  
        String s1 = scanner.nextLine();  
        String[] s2 = s1.split(",");  
        int[] str = new int[s2.length];  
        for (int i = 0; i < str.length; i++) {  
            str[i] = Integer.valueOf(s2[i]);  
        }  
        BinarySort bis = new BinarySort();  
        bis.binaryInsertSort(str);  
        System.out.println("排序后:");  
        for (int i = 0; i < str.length; i++) {  
            System.out.print(str[i]+" ");  
        }  
        scanner.close();  
    } 
}

5、冒泡排序

package algorithm;

public class BubbleSort {
	static int[] arr = {57,68,59,52};
	public static void main(String[] args) {
		int temp = 0;
		for (int i = 0; i < arr.length-1; i++) {
			for (int j = 0; j < arr.length-1-i; j++) {
				if(arr[j]>arr[j+1]){
					temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
		for (int a : arr) {
			System.out.print(a+"、");
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值