数据结构-排序

来源:互联网 发布:大数据修炼系统txt 编辑:程序博客网 时间:2024/06/08 06:59

排序

1.概念

  • 稳定性: 排序前的前后位置和排序后的前后位置一致
  • 内排序:排序过程中,所有待排序的记录全部被放置在内存中
  • 外排序:排序过程中,由于排序的记录数过多,不能同时放在内存中,整个排序过程需要在内外存之间多次数据交换才能进行

  • 插入排序类

    • 直接插入排序 稳定
    • 希尔排序 不稳定
  • 选择排序类
    • 简单选择排序 稳定
    • 堆排序 不稳定
  • 交换排序类
    • 冒泡排序 稳定
    • 快速排序 不稳定
  • 归并排序类
    • 归并排序 稳定

2.排序

2.1 冒泡排序

时间复杂度 n2

package com.sort;import java.util.Arrays;public class Bubble1 {    public static void main(String[] args) {        int[] arrs1 = { 9, 1, 5, 8, 3, 7, 4, 6, 2 };        int[] arrs2 = { 9, 1, 5, 8, 3, 7, 4, 6, 2 };        int[] arrs3 = { 9, 1, 5, 8, 3, 7, 4, 6, 2 };        bubble1(arrs1);        System.out.println();        bubble2(arrs2);        System.out.println();        bubble3(arrs3);    }    // 优化后的冒泡    public static void bubble3(int[] arrs) {        System.out.println("bubble3排序前:" + printArrays(arrs));        boolean flag = true;        for (int i = 0; i < arrs.length - 1 && flag == true; i++) {            flag = false;            for (int j = arrs.length - 2; j >= i; j--) {                if (arrs[j] > arrs[j + 1]) {                    swap(arrs, j, j + 1);                    flag = true;                }            }            System.out.println("第" + (i + 1) + "次排序结果:" + printArrays(arrs));        }    }    // 正宗冒泡    public static void bubble2(int[] arrs) {        System.out.println("bubble2排序前:" + printArrays(arrs));        for (int i = 0; i < arrs.length - 1; i++) {            for (int j = arrs.length - 2; j >= i; j--) {                if (arrs[j] > arrs[j + 1]) {                    swap(arrs, j, j + 1);                }            }            System.out.println("第" + (i + 1) + "次排序结果:" + printArrays(arrs));        }    }    // 最简单    public static void bubble1(int[] arrs) {        System.out.println("bubble1排序前:" + printArrays(arrs));        for (int i = 0; i < arrs.length - 1; i++) {            for (int j = i + 1; j < arrs.length; j++) {                if (arrs[i] > arrs[j]) {                    swap(arrs, i, j);                }            }            System.out.println("第" + (i + 1) + "次排序结果:" + printArrays(arrs));        }    }    public static String printArrays(int[] arrs) {        return Arrays.toString(arrs);    }    public static void swap(int[] arrs, int i, int j) {        int temp = arrs[i];        arrs[i] = arrs[j];        arrs[j] = temp;    }}

2.2 选择排序

与冒泡相比,少了许多交换swap操作。

时间复杂度 n2

package com.sort;import java.util.Arrays;public class Select1 {    public static void main(String[] args) {        int[] arrs1 = { 9, 1, 5, 8, 3, 7, 4, 6, 2 };        select1(arrs1);    }    public static void select1(int[] arrs) {        int minIndex = -1;        for (int i = 0; i < arrs.length - 1; i++) {            minIndex = i;            for (int j = i + 1; j < arrs.length; j++) {                if (arrs[j] < arrs[minIndex]) {                    minIndex = j;                }            }            if (minIndex != i) {                swap(arrs, i, minIndex);            }            print(i + 1, printArrays(arrs));        }    }    public static void print(int rowNumber, String dataString) {        System.out.println("第" + rowNumber + "行" + dataString);    }    public static String printArrays(int[] arrs) {        return Arrays.toString(arrs);    }    public static void swap(int[] arrs, int i, int j) {        int temp = arrs[i];        arrs[i] = arrs[j];        arrs[j] = temp;    }}

2.3 直接插入排序

时间复杂度 n2

有序的表中,将无序的表中的记录一个一个放入相应位置

package com.sort;import java.util.Arrays;public class DirectInsert {    public static void main(String[] args) {        int[] arrs1 = { 9, 1, 5, 8, 3, 7, 4, 6, 2 };        directInsert(arrs1);    }    public static void directInsert(int[] arrs) {        int temp = -1;        for (int i = 1; i < arrs.length; i++) {            // 第i个小于第i-1个。就是前一个小于后一个,则需要进行直接插入            if (arrs[i] < arrs[i - 1]) {                temp = arrs[i];                for (int j = i - 1; j >= 0; j--) {                    if (arrs[j] > temp) {                        arrs[j + 1] = arrs[j];                        // 如果j为0时,则因为后面不会在进行循环,所以此处需要判断j==0的情况                        if (j == 0) {                            arrs[j] = temp;                        }                    } else {                        arrs[j + 1] = temp;                        break;                    }                }            }            print(i, printArrays(arrs));        }    }    public static void print(int rowNumber, String dataString) {        System.out.println("第" + rowNumber + "行" + dataString);    }    public static String printArrays(int[] arrs) {        return Arrays.toString(arrs);    }    public static void swap(int[] arrs, int i, int j) {        int temp = arrs[i];        arrs[i] = arrs[j];        arrs[j] = temp;    }}

2.4 希尔排序

有一个步长step,每次根据这个步长进行调换元素。

不稳定的排序

package com.sort;import java.util.Arrays;public class Shell {    public static void main(String[] args) {        int[] arrs1 = { 9, 1, 5, 8, 3, 7, 4, 6, 2 };        System.out.println(printArrays(arrs1));        shell(arrs1);    }    public static void shell(int arrs[]) {        int step = arrs.length;        int temp = 0;        int rowNumber = 1;        int j = 0;        do {            step = step / 3 + 1;            for (int i = step; i < arrs.length; i++) {                if (arrs[i] < arrs[i - step]) {                    temp = arrs[i];                    for (j = i - step; j >= 0 && temp < arrs[j]; j -= step) {                        swap(arrs, j + step, j);                        print(rowNumber, printArrays(arrs));                    }                    arrs[j + step] = temp;                }                print(rowNumber, printArrays(arrs));                rowNumber++;            }            System.out.println();        } while (step > 1);    }    public static void print(int rowNumber, String dataString) {        System.out.println("第" + rowNumber + "次" + dataString);    }    public static String printArrays(int[] arrs) {        return Arrays.toString(arrs);    }    public static void swap(int[] arrs, int i, int j) {        int temp = arrs[i];        arrs[i] = arrs[j];        arrs[j] = temp;    }}

2.5 堆排序

  • 小顶堆:在完全二叉树的前提下,每个结点的值都小于或者等于其左右孩子结点的值
  • 大顶堆:在完全二叉树的前提下,每个结点的值都大于或者等于其左右孩子结点的值

不稳定的排序

先要构建大顶堆或小顶堆,然后进行排序,排序过程中又需要重构大顶堆或小顶堆。

时间复杂度 O(nlogn)

package com.sort;import java.util.Arrays;public class HeapSort {    public static void main(String[] args) {        int[] arrs1 = { 50, 10, 90, 30, 70, 40, 80, 60, 20 };        // , 11, 22, 33, 124, 54        // 构造大顶堆        heapOrder(arrs1);        System.out.println();        // 堆排序        heapSort(arrs1);    }    public static void heapSort(int[] arrs) {        System.out.println("原始样子:" + printArrays(arrs));        for (int i = arrs.length - 1; i > 0; i--) {            swap(arrs, 0, i);            heapAdjust(arrs, 0, i);            print(i, printArrays(arrs));        }    }    public static void print(int rowNumber, String dataString) {        System.out.println("第" + rowNumber + "次" + dataString);    }    public static String printArrays(int[] arrs) {        return Arrays.toString(arrs);    }    public static void swap(int[] arrs, int i, int j) {        int temp = arrs[i];        arrs[i] = arrs[j];        arrs[j] = temp;    }    // 将无序堆调整为大顶堆    public static void heapOrder(int[] arrs) {        System.out.println("构造大顶堆");        System.out.println(printArrays(arrs));        for (int i = arrs.length / 2 - 1; i >= 0; i--) {            System.out.println("以顶点" + i + "(" + arrs[i] + ")进行构造"                    + printArrays(arrs));            heapAdjust(arrs, i, arrs.length);        }    }    // 给定顶点,以该顶点为根节点,将该完全二叉树构造成大顶堆    public static void heapAdjust(int[] arrs, int start,            int arrsNeedAdjustLength) {        int temp, leftChildIndex, rightChildIndex;        temp = arrs[start];        // 因为用数组存储,第一个结点的下标是0。每个结点的        // 左孩子下标 = 2 * 结点位置 + 1        // 右孩子下 标= 2 * 节点位置 + 2        for (int j = 2 * start + 1; j < arrsNeedAdjustLength; j = 2 * j + 1) {            leftChildIndex = j;            rightChildIndex = j + 1;            // 如果存在右孩子,即右孩子的下标小于总的数组长度            // 并且右孩子的结点值大于左孩子的结点值            if (rightChildIndex < arrsNeedAdjustLength                    && arrs[leftChildIndex] < arrs[rightChildIndex]) {                // 那么将j赋值为右孩子的下标。默认是左孩子的下标。                j = rightChildIndex;            }            // 如果结点的值大于 左孩子和右孩子中的大者,则退出循环,            if (temp >= arrs[j]) {                // 即父节点大于子结点,无需交换                break;            } else {                // 否则,父节点的值等于子结点中大者的值                arrs[start] = arrs[j];                // start坐标设置为子结点坐标,用于下次遍历使用                start = j;            }        }        // 设置start坐标的值        arrs[start] = temp;    }}

2.6 归并排序

递归实现, 时间复杂度O(nlogn),空间复杂度O(n+logn)

非递归实现(迭代)

比较占用内存,但却效率高且稳定的算法。

递归实现

package com.sort;import java.util.Arrays;public class MergingSort {    public static void main(String[] args) {        int arrs1[] = { 50, 10, 90, 30, 70, 40, 80, 60, 20 };        int arrs2[] = { 50, 10, 90, 30, 70, 40, 80, 60, 20 };        System.out.println(printArrays(arrs1));        System.out.println(printArrays(arrs2));        msort(arrs1, arrs2, 0, arrs1.length - 1);        System.out.println(printArrays(arrs1));        System.out.println(printArrays(arrs2));    }    // 递归    public static void msort(int[] arrs1, int[] arrs2, int startIndex,            int endIndex) {        int midIndex;        int[] arrsTemp = new int[arrs1.length];        System.out.println(startIndex + " " + endIndex);        if (startIndex == endIndex) {            arrs2[startIndex] = arrs1[startIndex];        } else {            midIndex = (startIndex + endIndex) / 2;            msort(arrs1, arrsTemp, startIndex, midIndex);            msort(arrs1, arrsTemp, midIndex + 1, endIndex);            merge(arrsTemp, arrs2, startIndex, midIndex, endIndex);        }    }    public static void merge(int arrs1[], int arrs2[], int startIndex,            int midIndex, int endIndex) {        int j, k, l;        // 这个循环将midIndex前的数据和midIndex后的数据按大小合并。        // 类似于将两个有序的数组合并成一个数组。        for (j = midIndex + 1, k = startIndex; startIndex <= midIndex                && j <= endIndex; k++) {            if (arrs1[startIndex] < arrs1[j]) {                arrs2[k] = arrs1[startIndex++];            } else {                arrs2[k] = arrs1[j++];            }        }        // 数组后面多余的数        if (startIndex <= midIndex) {            for (l = 0; l <= midIndex - startIndex; l++) {                arrs2[k + l] = arrs1[startIndex + l];            }        }        // 数组后面多余的数        if (j <= endIndex) {            for (l = 0; l <= endIndex - j; l++) {                arrs2[k + l] = arrs1[j + l];            }        }    }    public static void print(int rowNumber, String dataString) {        System.out.println("第" + rowNumber + "次" + dataString);    }    public static String printArrays(int[] arrs) {        return Arrays.toString(arrs);    }    public static void swap(int[] arrs, int i, int j) {        int temp = arrs[i];        arrs[i] = arrs[j];        arrs[j] = temp;    }}

迭代实现

package com.sort;import java.util.Arrays;public class MergingSort2 {    public static void main(String[] args) {        // 第一个数 0 用于占位,,,        int arrs1[] = { 0, 50, 10, 90, 30, 70, 40, 80, 60, 20 };        // , 11, 22, 33, 124, 54        int arrs2[] = { 0, 50, 10, 90, 30, 70, 40, 80, 60, 20 };        System.out.println(printArrays(arrs1));        System.out.println(printArrays(arrs2));        int k = 1;        while (k < arrs1.length) {            mergePass(arrs1, arrs2, k, arrs1.length - 1);            k = 2 * k;            mergePass(arrs2, arrs1, k, arrs1.length - 1);            k = 2 * k;        }        System.out.println(printArrays(arrs1));        System.out.println(printArrays(arrs2));    }    // 迭代    public static void mergePass(int[] arrs1, int[] arrs2, int startIndex,            int endIndex) {        int i = 1, j;        while (i <= endIndex - 2 * startIndex + 1) {            merge(arrs1, arrs2, i, i + startIndex - 1, i + 2 * startIndex - 1);            i = i + 2 * startIndex;        }        if (i < endIndex - startIndex + 1) {            merge(arrs1, arrs2, i, i + startIndex - 1, endIndex);        } else {            for (j = i; j <= endIndex; j++) {                arrs2[j] = arrs1[j];            }        }    }    public static void merge(int[] arrs1, int[] arrs2, int startIndex,            int midIndex, int endIndex) {        int j, k, l;        // 这个循环将midIndex前的数据和midIndex后的数据按大小合并。        // 类似于将两个有序的数组合并成一个数组。        for (j = midIndex + 1, k = startIndex; startIndex <= midIndex                && j <= endIndex; k++) {            if (arrs1[startIndex] < arrs1[j]) {                arrs2[k] = arrs1[startIndex++];            } else {                arrs2[k] = arrs1[j++];            }        }        // 数组后面多余的数        if (startIndex <= midIndex) {            for (l = 0; l <= midIndex - startIndex; l++) {                arrs2[k + l] = arrs1[startIndex + l];            }        }        // 数组后面多余的数        if (j <= endIndex) {            for (l = 0; l <= endIndex - j; l++) {                arrs2[k + l] = arrs1[j + l];            }        }    }    public static void print(int rowNumber, String dataString) {        System.out.println("第" + rowNumber + "次" + dataString);    }    public static String printArrays(int[] arrs) {        return Arrays.toString(arrs);    }    public static void swap(int[] arrs, int i, int j) {        int temp = arrs[i];        arrs[i] = arrs[j];        arrs[j] = temp;    }}

2.7 快速排序

时间复杂度 nlogn

空间复杂度 logn

package com.sort;import java.util.Arrays;public class QuickSort {    public static void main(String[] args) {        // 第一个数 0 用于占位,,,        int arrs1[] = { 0, 50, 10, 90, 30, 70, 40, 80, 60, 20 };        System.out.println(printArrays(arrs1));        qSort(arrs1, 0, arrs1.length - 1);        System.out.println(printArrays(arrs1));    }    public static void qSort(int[] arrs, int low, int high) {        int pivot;        if (low < high) {            pivot = partition(arrs, low, high);            qSort(arrs, low, pivot - 1);            qSort(arrs, pivot + 1, high);        }    }    public static int partition(int[] arrs, int low, int high) {        int pivotkey = arrs[low];        while (low < high) {            while (low < high && arrs[high] >= pivotkey) {                high--;            }            swap(arrs, low, high);            while (low < high && arrs[low] <= pivotkey) {                high--;            }            swap(arrs, low, high);        }        return low;    }    public static void print(int rowNumber, String dataString) {        System.out.println("第" + rowNumber + "次" + dataString);    }    public static String printArrays(int[] arrs) {        return Arrays.toString(arrs);    }    public static void swap(int[] arrs, int i, int j) {        int temp = arrs[i];        arrs[i] = arrs[j];        arrs[j] = temp;    }}
原创粉丝点击