交换数组两个变量的位置
不引入第三个变量交换两个变量的值
a = a + b
b = a - b
a = a - b
引入第三个变量交换两个变量的值
temp = a
a = b
b = temp
排序算法
- 冒泡排序
- 选择排序
- 插入排序
- 希尔排序
- 快速排序
- 归并排序
- 堆排序
- 基数排序
冒泡排序
其核心就是两两比较,但是不是和所有人比价你
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
int data[] = new int[n];
for (int i = 0; i < n; i++) {
data[i] = cin.nextInt();
}
// Map size() list.size();
// n = 5
//data 0 1 2 3 4
for (int i = 0, len = data.length; i < len - 1; i++) {
for (int j = 0; j < len - 1 - i; j++) {
if (data[j] > data[j + 1]) {
// 交换 不让你引入第三个变量 交换 a b的值
int temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
for(int i = 0 ; i < n; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
}
选择排序
拿出来最高的这个和所有人去比较,得出位置。
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
int data[] = new int[n];
for(int i = 0 ; i < n; i ++) {
data[i] = cin.nextInt();
}
for(int i = n - 1 ; i > 0; i--) {
for(int j = i - 1; j >= 0 ; j--) {
if(data[i] < data[j]) {
int temp = data[j];
data[j] = data[i];
data[i] = temp;
}
}
}
for(int i = 0 ; i < n; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
}
插入排序
对一个有序的序列插入,插入进去后保证还是有序的。
public static void main(String[] args) {
// 4 2 3 1
// 第一步: 4
// 第二步: 2 4
// 第三步: 2 3 4
// 第四部步: 1 2 3 4
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
int data[] = new int[n];
for(int i = 0 ; i < n; i ++) {
data[i] = cin.nextInt();
}
for(int i = 1 ; i < n; i++) { //每次加的数进来
for(int j = i; j > 0 ; j--) { //这个j表示的是已经排好序的序列
if(data[j] < data[j - 1]) {
//交换 不让你引入第三个变量 交换 a b的值
int temp = data[j];
data[j] = data[j - 1];
data[j - 1] = temp;
}else {
break;
}
}
}
for(int i = 0 ; i < n; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
}
希尔排序
对插入排序的改进。步长,分组
public static void main(String[] args) {
// 4 1 2 3 5
// 第一步
//len = 5 表示有5个数字
// step = len /2 => 5/2 =2;
// 4 2 =>分出来的还是进行一个插入排序 2 4
// 1 3 => 1 3
// 5=> 5
// 2 1 4 3 5
//100 / 2 = 50
// 50 / 2 => 25
//25 /2
//step = 1排完
// 第二步 step = step / 2 =>1
// 第四部步: 1 2 3 4
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
int data[] = new int[n];
for (int i = 0; i < n; i++) {
data[i] = cin.nextInt();
}
int step = n;
while(step >= 1) {
step = step / 2;
for(int i = step ; i < n; i ++) {
for(int j = i ;j - step >= 0; j-= step) {
if(data[j] < data[j - step]) {
int temp = data[j];
data[j] = data[j - step];
data[j - step] = temp;
}else {
break;
}
}
}
}
for(int i = 0 ; i < n; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
}
快速排序
public static void qSort(int data[], int left, int right) {
int ll = left;// 从左边找的位置
int rr = right; // 从右边找的位置
int base = data[left]; // 取第一个作为基准数
//Sort
// 1 2 3 4 5
while (ll < rr) {
// 从后面往前找到比基准数小的数进行对换
while (ll < rr && data[rr] >= base) {
rr--;
}
if (ll < rr) { // 为了怕是 没找到
int temp = data[rr];
data[rr] = data[ll];
data[ll] = temp;
ll++;
}
// 从前面往后面找比基准数大的进行对换
while (ll < rr && data[ll] <= base) {
ll++;
}
if (ll < rr) {
int temp = data[rr];
data[rr] = data[ll];
data[ll] = temp;
rr--;
}
}
System.out.println("以Base=" +base+ "的排序结果");
print(data);
// 以基准数分为3部分,左边的比之小,右边比之大 我们要做的就是一把这左边和右边分别进行快速排序
if (ll > left) {
qSort(data, left, ll - 1);
}
if (rr < right) {
qSort(data, ll+1, right);
}
}
public static void print(int data[]) {
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int data[] = { 45, 28, 80, 90, 50, 16, 100, 10 };
qSort(data, 0, data.length - 1);
print(data);
}
归并排序
如果要对一个数组进行排序,可以先(递归地)将它分成两半分别排序,然后将结果归并起来。归并算法最吸引人的性质是它能保证将任意长度为N的数组排序所需时间和NlogN成正比;缺点则是它所需的额外空间和N成正比。
public class Merge {
private static Comparable[] b;
public static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
public static void merge(Comparable[] a, int lo, int mid, int hi) {
int i = lo;
int j = mid + 1;
for (int k = lo; k < hi + 1; k++) {
b[k] = a[k];
}
for (int k = lo; k < hi + 1; k++) {
if (i > mid) {
a[k] = b[j++];
} else if (j > hi) {
a[k] = b[i++];
} else if (less(b[i], b[j])) {
a[k] = b[i++];
} else {
a[k] = b[j++];
}
}
}
/**
* 自顶向下和自底向上
*
* @param a
*/
public static void sort(Comparable[] a) {
b = new Comparable[a.length];
// 自顶向下
sort(a, 0, a.length - 1);
//自底向上
// for (int i = 1; i < a.length; i++) {
// for (int lo = 0; lo < a.length - i; lo += i + i) {
// merge(a, lo, lo + i - 1, Math.min(lo + i + i - 1, a.length - 1));
// }
// }
}
public static void sort(Comparable[] a, int lo, int hi) {
if (hi <= lo) {
return;
}
int mid = lo + (hi - lo) / 2;
sort(a, lo, mid);
sort(a, mid + 1, hi);
merge(a, lo, mid, hi);
}
public static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
Integer[] a = new Integer[10];
for (int i = 0; i < 10; i++) {
a[i] = (int) (Math.random() * 10 + 1);
}
show(a);
sort(a);
show(a);
}
}
稳定排序和不稳定排序
假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变
即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的
1 3 1 5 => 1 1 3 5 稳定的
1 3 1 5 => 1 1 3 5 不稳定的