数据结构各种排序算法的java程序实现

各种排序算法的java程序实现

数据结构中一些常用算法的对比,代码是一位大神博主的,做了一些修改,后来没用Java了,有对排序算法感兴趣的同学可以作为参考,如果侵犯了权益请联系我,我把文章删除了。

// An highlighted block
import java.util.Arrays;
 
public class zjcr {
    
    
	
	public static void main(String[] args) {
    
    
		System.out.println("排序开始");
		long startTime = System.nanoTime(); //获取开始时间 
		 
		int []array={
    
    45,48897,1,754,5,787,12,25,12,4,62,31,24,654,9894,65,7,21,894,94,9456,13,67,29,46,10,61,98,45,561,2,18};
		//insertSort(array);	//1.直接插入
		//sheelSort(array);		//2.希尔排序
		//selectSort(array);	//3.简单选择排序
		//heapSort(array);		//4.堆排序
		//bubbleSort(array);	//5.冒泡排序
		//quickSort(array, 0, array.length-1);//6.快速排序  
		//mergeSort(array);		//7.归并排序
		System.out.println(Arrays.toString(array));
		long endTime = System.nanoTime(); //获取结束时间 
		System.out.println("程序运行时间:" + (endTime - startTime) + "ns"+"\n排序完成");
	}
	
	public static void insertSort(int[] a) {
    
    
		int insertNum; // 要插入的数
		for (int i = 1; i < a.length; i++) {
    
    
			insertNum = a[i];
			int j = i - 1;
			while (j >= 0 && a[j] > insertNum) {
    
    // 将大于insertNum的数向后移动一格
				a[j + 1] = a[j];
				j--;
			}
			a[j + 1] = insertNum;
		}
		}
	public static void sheelSort(int[] a) {
    
    
		int length = a.length;
		while (length != 0) {
    
    
			length = length / 2;
			System.out.println("length变化: " + length);
			for (int x = 0; x < length; x++) {
    
     	// 分组个数
				for (int i = x + length; i < a.length; i += length) {
    
    
					int j = i - length; 	// j为有序序列最后一位的位数
					int insertNum = a[i]; 	// 要插入的元素
					for (; j >= 0 && insertNum < a[j]; j -= length) {
    
    
						a[j + length] = a[j];	// 向后移动length位
					}
					a[j + length] = insertNum;
				}
			}
		}
	}
	
	/**
	 * 3.简单选择排序    常用于取序列中最大最小的几个数时。
	 * 平均时间复杂度	最坏时间复杂度	空间复杂度	是否稳定
	 * O(n^2) 		O(n^2)		O(1)	不是
	 * 	(如果每次比较都交换,那么就是交换排序;如果每次比较完一个循环再交换,就是简单选择排序。)
	 * 	遍历整个序列,将最小的数放在最前面。
	 * 	遍历剩下的序列,将最小的数放在最前面。
	 * 	重复第二步,直到只剩下一个数。
	 * 
	 ***如何写成代码:
	 *	1.首先确定循环次数,并且记住当前数字和当前位置。
	 *	2.将当前位置后面所有的数与当前数字进行对比,小数赋值给key,并记住小数的位置。
	 *	3.比对完成后,将最小的值与第一个数的值交换。
	 *	4.重复2、3步。
	 */
	public static void selectSort(int[] a) {
    
    
		int length = a.length;
		for (int i = 0; i < length; i++) {
    
    			// 循环次数
			int key = a[i];
			int position = i;
			for (int j = i + 1; j < length; j++) {
    
    	// 选出最小值和位置
				if (a[j] < key) {
    
    
					key = a[j];
					position = j;
				}
			}
			a[position] = a[i];			// 交换位置
			a[i] = key;
		}
	}
	
	/**
	 * 4.堆排序   对简单选择排序的优化。
	 * 平均时间复杂度	最坏时间复杂度	空间复杂度	是否稳定
	 * O(nlogn)		O(nlogn)	O(1)	不是
	 *	将序列构建成大顶堆。
	 *	将根节点与最后一个节点交换,然后断开最后一个节点。
	 *	重复第一、二步,直到所有节点断开。
	 */
	public static void heapSort(int[] a) {
    
    
		System.out.println("开始排序");
		int arrayLength = a.length;
		// 循环建堆
		for (int i = 0; i < arrayLength - 1; i++) {
    
    
			// 建堆
			buildMaxHeap(a, arrayLength - 1 - i);
			// 交换堆顶和最后一个元素
			swap(a, 0, arrayLength - 1 - i);
			System.out.println(Arrays.toString(a));
		}
	}
 
	private static void swap(int[] data, int i, int j) {
    
    
		int tmp = data[i];
		data[i] = data[j];
		data[j] = tmp;
	}
 
	// 对data数组从0到lastIndex建大顶堆
	private static void buildMaxHeap(int[] data, int lastIndex) {
    
    
		// 从lastIndex处节点(最后一个节点)的父节点开始
		for (int i = (lastIndex - 1) / 2; i >= 0; i--) {
    
    
			// k保存正在判断的节点
			int k = i;
			// 如果当前k节点的子节点存在
			while (k * 2 + 1 <= lastIndex) {
    
    
				// k节点的左子节点的索引
				int biggerIndex = 2 * k + 1;
				// 如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在
				if (biggerIndex < lastIndex) {
    
    
					// 若果右子节点的值较大
					if (data[biggerIndex] < data[biggerIndex + 1]) {
    
    
						// biggerIndex总是记录较大子节点的索引
						biggerIndex++;
					}
				}
				// 如果k节点的值小于其较大的子节点的值
				if (data[k] < data[biggerIndex]) {
    
    
					// 交换他们
					swap(data, k, biggerIndex);
					// 将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
					k = biggerIndex;
				} else {
    
    
					break;
				}
			}
		}
	}
	
    
    /**
     * 5.冒泡排序    一般不用。
     * 平均时间复杂度	最坏时间复杂度	空间复杂度	是否稳定
     * O(n^2) 		O(n^2)		O(1)	是
	 *	将序列中所有元素两两比较,将最大的放在最后面。
	 *	将剩余序列中所有元素两两比较,将最大的放在最后面。
	 *	重复第二步,直到只剩下一个数。
	 *	
	 ***如何写成代码:
	 *	1.设置循环次数。
	 *	2.设置开始比较的位数,和结束的位数。
	 *	3.两两比较,将最小的放到前面去。
	 *	4.重复2、3步,直到循环次数完毕。
	 *
     */
	public static void bubbleSort(int[] a) {
    
    
		int length = a.length;
		int temp;
		for (int i = 0; i < length; i++) {
    
    
			for (int j = 0; j < length - i - 1; j++) {
    
    
				if (a[j] > a[j + 1]) {
    
    
					temp = a[j];
					a[j] = a[j + 1];
					a[j + 1] = temp;
				}
			}
		}
	}
 
	/**
	 * 6.快速排序		要求时间最快时。
	 * 平均时间复杂度	最坏时间复杂度	空间复杂度		是否稳定
	 * O(nlogn) 	O(n^2)		O(logn)	不是
	 *	选择第一个数为p,小于p的数放在左边,大于p的数放在右边。
	 *	递归的将p左边和右边的数都按照第一步进行,直到不能递归。
	 */
	public static void quickSort(int[] numbers, int start, int end) {
    
    
		if (start < end) {
    
    
			int base = numbers[start];// 选定的基准值
			int temp;
			int i = start, j = end;
			do {
    
    
				while ((numbers[i] < base) && (i < end))
					i++;
				while ((numbers[j] > base) && (j > start))
					j--;
				if (i <= j) {
    
    
					temp = numbers[i];
					numbers[i] = numbers[j];
					numbers[j] = temp;
					i++;
					j--;
				}
			} while (i <= j);
			if (start < j)
				quickSort(numbers, start, j);
			if (end > i)
				quickSort(numbers, i, end);
		}
	}
 
	/**
	 * 7.归并排序		速度仅次于快排,内存少的时候使用,可以进行并行计算的时候使用。
	 * 平均时间复杂度	最坏时间复杂度	空间复杂度	是否稳定
	 * O(nlogn) 	O(nlogn)	O(n)	是
	 *	选择相邻两个数组成一个有序序列。
	 *	选择相邻的两个有序序列组成一个有序序列。
	 *	重复第二步,直到全部组成一个有序序列。
	 */
	public static void mergeSort(int[] arr) {
    
    
		int[] temp = new int[arr.length];// 在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
		mergeSort(arr, 0, arr.length - 1, temp);
	}
 
	private static void mergeSort(int[] arr, int left, int right, int[] temp) {
    
    
		if (left < right) {
    
    
			int mid = (left + right) / 2;
			mergeSort(arr, left, mid, temp);// 左边归并排序,使得左子序列有序
			mergeSort(arr, mid + 1, right, temp);// 右边归并排序,使得右子序列有序
			merge(arr, left, mid, right, temp);// 将两个有序子数组合并操作
		}
	}
 
	private static void merge(int[] arr, int left, int mid, int right,
			int[] temp) {
    
    
		int i = left;// 左序列指针
		int j = mid + 1;// 右序列指针
		int t = 0;// 临时数组指针
		while (i <= mid && j <= right) {
    
    
			if (arr[i] <= arr[j]) {
    
    
				temp[t++] = arr[i++];
			} else {
    
    
				temp[t++] = arr[j++];
			}
		}
		while (i <= mid) {
    
    // 将左边剩余元素填充进temp中
			temp[t++] = arr[i++];
		}
		while (j <= right) {
    
    // 将右序列剩余元素填充进temp中
			temp[t++] = arr[j++];
		}
		t = 0;
		// 将temp中的元素全部拷贝到原数组中
		while (left <= right) {
    
    
			arr[left++] = temp[t++];
		}
	}
	
	
	/**
	 * 8.基数排序		用于大量数,很长的数进行排序时。
	 * 平均时间复杂度	最坏时间复杂度	空间复杂度	是否稳定
	 * O(N∗M)		O(N∗M)		O(M)	是
	 * 将所有的数的个位数取出,按照个位数进行排序,构成一个序列。
	 * 将新构成的所有的数的十位数取出,按照十位数进行排序,构成一个序列。
	 */
	public static void sort(int[] number, int d) {
    
    
		int k = 0;
		int n = 1;
		int m = 1;
		int[][] temp = new int[number.length][number.length];
		int[] order = new int[number.length];
		while (m <= d) {
    
    
			for (int i = 0; i < number.length; i++) {
    
    
				int lsd = ((number[i] / n) % 10);
				temp[lsd][order[lsd]] = number[i];
				order[lsd]++;
			}
			for (int i = 0; i < d; i++) {
    
    
				if (order[i] != 0)
					for (int j = 0; j < order[i]; j++) {
    
    
						number[k] = temp[i][j];
						k++;
					}
				order[i] = 0;
			}
			n *= 10;
			k = 0;
			m++;
		}
	} 



	}
	

猜你喜欢

转载自blog.csdn.net/qq_40595787/article/details/117479749