import java.util.ArrayList;
import java.util.Arrays;
public class ThreadTest {
public static void main(String[] args) {
int ar[] = {3,1,5,8,4,2,6,7,15,16,10,13,14,12,11,17,9};
//直接插入排序
//insertSort(ar);
//希尔排序
//shellSort(ar);
//选择排序
//selectSort(ar);
//冒泡排序
//bubbleSort(ar);
//快速排序
//quickSort(ar);
//归并排序
//mergingSort(ar);
//基数排序
//radixSort(ar);
//堆排序
heapSort(ar);
}
/**
* 直接插入排序
* @param array
*/
public static void insertSort(int[] array){
for(int i=1;i<array.length;i++){ //假设第一位是有序的,从数组的第二位开始排序
int temp = array[i]; //temp为即将要排序的数值
int j = i-1; //j为已经排好序的数组的最后一位
for(;j>=0 && array[j]>temp;j--){ //将temp与已经排好序的数组进行比较,大的数放在已排好序的数组后面
array[j+1] = array[j];
}
array[j+1] = temp; //j--,小的数往前面放
}
System.out.println("直接插入排序:"+Arrays.toString(array));
}
/**
* 希尔排序
* @param array
*/
public static void shellSort(int[] array){
int i,j; //序列循环标记
int temp; //即将排序的数值
int gap = 1; //分组大小
int len = array.length; //数组长度
while(gap<len/3){ //如果数组长度大于等于6
gap = gap*3+1; //最大分组数为4
}
for(;gap>0;gap = gap/3){
for(i=gap; i<len; i++){
temp = array[i];
for(j=i-gap; j>=0 && array[j]>temp; j=j-gap){
array[j+gap] = array[j];
}
array[j+gap] = temp;
}
}
System.out.println("希尔排序:"+Arrays.toString(array));
}
/**
* 选择排序
* @param array
*/
public static void selectSort(int[] array){
for(int i=0; i<array.length - 1; i++){ //将数组分为有序和无序两个区,初始状态:无序区为R[1..n],有序区为空
int min = i; //先假设无序最小值为R[0],即假设无序区的第一个值为最小值
for(int j=i+1; j<array.length; j++){ //循环比较无序区的数组,得到最小值及下标
if(array[j]<array[min]){
min = j;
}
}
if(min != i){ //如果得到的最小值下标和预先假设的最小值下标不一致,交换两个数值位置(及有序区的末尾)
int temp = array[min];
array[min] = array[i];
array[i] = temp;
}
}
System.out.println("选择排序:"+Arrays.toString(array));
}
/**
* 冒泡排序
* @param array
*/
public static void bubbleSort(int[] array){
for(int i=1; i<array.length; i++){ //每次需要冒泡的待排序数组
for(int j=0; j<array.length - i; j++){ //循环待排序数组
if(array[j]>array[j+1]){ //从第一位开始相邻的两个值进行比较,并排序(大的值在后)
int temp = array[j+1];
array[j+1] = array[j];
array[j] = temp;
}
}
}
System.out.println("冒泡排序:"+Arrays.toString(array));
}
/**
* 快速排序
* @param array
*/
public static void quickSort(int[] array){
_quickSort(array, 0, array.length - 1);
System.out.println("快速排序:"+Arrays.toString(array));
}
private static void _quickSort(int[] list, int low, int high) {
if (low < high) {
int middle = getMiddle(list, low, high); //将list数组进行一分为二
_quickSort(list, low, middle - 1); //对低字表进行递归排序
_quickSort(list, middle + 1, high); //对高字表进行递归排序
}
}
private static int getMiddle(int[] list, int low, int high) {
int tmp = list[low]; //数组的第一个作为中轴
while (low < high) {
while (low < high && list[high] >= tmp) {
high--;
}
list[low] = list[high]; //比中轴小的记录移到低端
while (low < high && list[low] <= tmp) {
low++;
}
list[high] = list[low]; //比中轴大的记录移到高端
}
list[low] = tmp; //中轴记录到尾
return low; //返回中轴的位置
}
/**
* 归并排序
* @param array
*/
public static void mergingSort(int[] array) {
sort(array, 0, array.length - 1);
System.out.println("归并排序:"+Arrays.toString(array));
}
private static void sort(int[] data, int left, int right) {
if (left < right) {
//找出中间索引
int center = (left + right) / 2;
//对左边数组进行递归
sort(data, left, center);
//对右边数组进行递归
sort(data, center + 1, right);
//合并
merge(data, left, center, right);
}
}
private static void merge(int[] data, int left, int center, int right) {
int[] tmpArr = new int[data.length];
int mid = center + 1;
//third记录中间数组的索引
int third = left;
int tmp = left;
while (left <= center && mid <= right) {
//从两个数组中取出最小的放入中间数组
if (data[left] <= data[mid]) {
tmpArr[third++] = data[left++];
} else {
tmpArr[third++] = data[mid++];
}
}
//剩余部分依次放入中间数组
while (mid <= right) {
tmpArr[third++] = data[mid++];
}
while (left <= center) {
tmpArr[third++] = data[left++];
}
//将中间数组中的内容复制回原数组
while (tmp <= right) {
data[tmp] = tmpArr[tmp++];
}
}
/**
* 基数排序
* @param array
*/
public static void radixSort(int[] array) {
//首先确定排序的趟数;
int max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
int time = 0;
//判断位数;
while (max > 0) {
max /= 10;
time++;
}
//建立10个队列;
ArrayList<ArrayList<Integer>> queue = new ArrayList<>();
for (int i = 0; i < 10; i++) {
ArrayList<Integer> queue1 = new ArrayList<>();
queue.add(queue1);
}
//进行time次分配和收集;
for (int i = 0; i < time; i++) {
//分配数组元素;
for (int anArray : array) {
//得到数字的第time+1位数;
int x = anArray % (int)Math.pow(10, i + 1) / (int)Math.pow(10, i);
ArrayList<Integer> queue2 = queue.get(x);
queue2.add(anArray);
queue.set(x, queue2);
}
int count = 0;//元素计数器;
//收集队列元素;
for (int k = 0; k < 10; k++) {
while (queue.get(k).size() > 0) {
ArrayList<Integer> queue3 = queue.get(k);
array[count] = queue3.get(0);
queue3.remove(0);
count++;
}
}
}
System.out.println("基数排序:"+Arrays.toString(array));
}
/**
* 堆排序
* @param array
*/
public static void heapSort(int[] array) {
/*
* 第一步:将数组堆化
* beginIndex = 第一个非叶子节点。
* 从第一个非叶子节点开始即可。无需从最后一个叶子节点开始。
* 叶子节点可以看作已符合堆要求的节点,根节点就是它自己且自己以下值为最大。
*/
int len = array.length - 1;
int beginIndex = (len - 1) >> 1;
for (int i = beginIndex; i >= 0; i--) {
maxHeapify(i, len, array);
}
/*
* 第二步:对堆化数据排序
* 每次都是移出最顶层的根节点A[0],与最尾部节点位置调换,同时遍历长度 - 1。
* 然后从新整理被换到根节点的末尾元素,使其符合堆的特性。
* 直至未排序的堆长度为 0。
*/
for (int i = len; i > 0; i--) {
swap(0, i, array);
maxHeapify(0, i - 1, array);
}
System.out.println("堆排序:"+Arrays.toString(array));
}
private static void swap(int i, int j, int[] arr) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
/**
* 调整索引为 index 处的数据,使其符合堆的特性。
*
* @param index 需要堆化处理的数据的索引
* @param len 未排序的堆(数组)的长度
*/
private static void maxHeapify(int index, int len, int[] arr) {
int li = (index << 1) + 1; // 左子节点索引
int ri = li + 1; // 右子节点索引
int cMax = li; // 子节点值最大索引,默认左子节点。
if (li > len) {
return; // 左子节点索引超出计算范围,直接返回。
}
if (ri <= len && arr[ri] > arr[li]) // 先判断左右子节点,哪个较大。
{ cMax = ri; }
if (arr[cMax] > arr[index]) {
swap(cMax, index, arr); // 如果父节点被子节点调换,
maxHeapify(cMax, len, arr); // 则需要继续判断换下后的父节点是否符合堆的特性。
}
}
}
java常用算法
最新推荐文章于 2024-08-20 00:54:19 发布