Java数据结构学习Day2_Java基础排序算法
1.冒泡排序
冒泡排序就是用双重循环,从数组的头部开始遍历,如果当前数比后一个数大,则调换两者的位置,时间复杂度为O(n^2),冒泡排序很好理解,就是相邻两个数字交换位置即可
package Ivan.sort;
public class BubbleSort {
public static void main(String[] args) {
int arr[] = {3, 4, 5, 12, -1, -34};
int temp = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
if (arr[i] < arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
2.选择排序
第一次从arr[0] - arr[n-1]中选取最小值与arr[0]交换,第二次从arr[1]-arr[n-1]中再选最小值和arr[1]交换,以此类推,时间复杂度也是o(n^2),选择排序也比较简单,多看两遍代码就能理解,每次选择剩余数组中最小的数和剩余数组中的第一个数交换位置
package Ivan.sort;
public class SelectSort {
public static void main(String[] args) {
int arr[] = {1, -1, 3, -4, -5, 5};
for (int i = 0; i < arr.length; i++) {
int minIndex = i;
int min = arr[i];
for (int j = i + 1; j < arr.length; j++) {
if (min > arr[j]) {
min = arr[j];
minIndex = j;
}
}
if (minIndex != i) {
arr[minIndex] = arr[i];
arr[i] = min;
}
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
3.插入排序
把n个待排序的元素看成一个有序表和一个无序表,无序表中有n-1个元素,有序表中只有一个元素,每次排序从无序表中取出一个元素插入到有序表中,最后返回有序表,最坏的时间复杂度也是o(n^2)
package Ivan.sort;
public class insertSort {
public static void main(String[] args) {
int arr[] = {1, -1, 3, -4, -5, 5};
for (int i = 1; i < arr.length; i++) {
int insertValue = arr[i];
int index = i - 1;
while (index >= 0 && insertValue < arr[index]) {
arr[index + 1] = arr[index];
index--;
}
arr[index + 1] = insertValue;
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
4.希尔排序
希尔排序也是一种插入排序,是由简单排序改进之后的一个更高效的版本,把数组进行一定增量的分组,对每组使用直接插入排序算法排序,希尔排序比较难理解的就是步长,可以理解成把第i个元素和i+步长的元素比较大小,交换位置或是移动位置
package Ivan.sort;
public class ShellSort {
public static void main(String[] args) {
int arr[] = {1, -1, 3, -4, -5, 5, 34, 67, -4, -4, 15, 6, -523};
Shell2(arr);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
//交换式
public static void Shell(int arr[]) {
int temp = 0;
for (int i = arr.length / 2; i > 0; i /= 2) {
for (int j = i; j < arr.length; j++) {
for (int k = j - i; k >= 0; k -= i) {
if (arr[k] > arr[k + i]) {
temp = arr[k];
arr[k] = arr[k + i];
arr[k + i] = temp;
}
}
}
}
}
//移动式
public static void Shell2(int arr[]) {
for (int i = arr.length / 2; i > 0; i /= 2) { //i为步长
for (int j = i; j < arr.length; j++) {
int k = j;
int temp = arr[j];
if (arr[j] < arr[j - i]) {
while (k - i >= 0 && temp < arr[k - i]) {
arr[k] = arr[k - i];
k -= i;
}
arr[k] = temp;
}
}
}
}
}
5.快速排序
快排是对冒泡排序的一种改进,基本思想是:经过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的所有数据要小,再按此方法对这两部分数据进行快排,递归的思路,快排比较难理解的就是找一个基准数,把左右两边的数都拍好以后,再对左右两边的分别进行快排,要理解递归的思路
package Ivan.sort;
public class quickSort {
public static void main(String[] args) {
int arr[] = {1, -1, 3, -4, -5, 5, 34, 67, -4, -4, 15, 6};
quickSort(arr, 0, arr.length - 1);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
public static void quickSort(int[] arr, int left, int right) {
int l = left;
int r = right;
int temp = 0;
int p = arr[(left+right)/2];
while (l<r){
//找到左边比p大的值
while (arr[l]<p){
l++;
}
//找到右边比p小的值
while (arr[r] > p){
r--;
}
if (l>=r) break;
//找到了就交换位置
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
//交换完后发现arr[l] == p,前移
if (arr[l] == p){
r -= 1;
}
if (arr[r] == p){
l += 1;
}
}
//递归左边和右边
//如果l==r,必须l++,r--,否则栈溢出
if (l==r){
l++;
r--;
}
if (left<r) quickSort(arr, left, r);
if (right>l) quickSort(arr, l, right);
}
}