8大排序(内涵代码,图解,思路)

本文详细介绍了Java中常见的几种排序算法实现,包括Comparable接口实现的比较排序,冒泡排序、选择排序、插入排序的基本原理和优化版代码,以及希尔排序、快速排序、归并排序和基数排序的详细过程。通过对各种排序算法的理解和实践,有助于提升编程能力并理解不同排序算法的时间复杂度和适用场景。

排序

一、简单排序

1.1Comparable接口

需求

​ 1.定义一个学生类Student ,具有年龄age和姓名username两个属性,并通过Comparable接口提供比较规则;

​ 2.定义测试类Test ,在测试类Test中定义测试方法Comparable getMax(Comparable C1,Comparable C2)完成测试

package com.zhao.sort;
//比较两个学生的年龄
public class TestComparable {
    public static void main(String[] args) {
        Student student = new Student(18,"李四");
        Student student2 = new Student(20,"李四");

        Comparable max = getMax(student, student2);
        System.out.println(max);
    }

    public static Comparable getMax(Comparable c1,Comparable c2){
        int result = c1.compareTo(c2);
        if (result >= 0){
            return c1;
        }else {
            return c2;
        }
    }
}

class Student implements Comparable<Student>{
    private int age;
    private String name;

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public int compareTo(Student o) {
        return this.age - o.age;
    }
}

1.2冒泡排序

排序原理:

​ 1.比较相邻的元素。如果前一个元素比后一个元素大 ,就交换这两个元素的位置。

​ 2.对每一对相邻元素做同样的工作 ,从开始第一对元素到结尾的最后一对元素。最终最后位置的元素就是最大值。

​ 时间复杂度为(n^2)

类名Bubble
构造方法Buffle():创建Bubble对象
成员方法1.public static void sort(Comparable[] v):对数组内的元素进行排序
2.private static boolean greater(Comparable v,Comparable W);判断v是否大于w
3.private static void exch(Comparable[] a,int i,intj)。交换a数组中,索引和索引j处的值
package com.zhao.sort;

import java.util.Arrays;

public class BubbleTest {
    public static void main(String[] args) {
        Integer[] arr = {5,4,2,3,6,1};
        Bubble.sort(arr);

        System.out.println(Arrays.toString(arr));

    }
}

//冒泡排序
class Bubble{
    //对数组内的元素进行排序
    public static void sort(Comparable[] v){
        for (int i=v.length-1;i>0;i--){
            for (int j=0;j<i;j++){
                if (greater(v[j],v[j+1])){
                    exch(v,j,j+1);
                }
            }
        }

    }
    //判断v是否大于w
    private static boolean greater(Comparable v,Comparable w){
        return v.compareTo(w) > 0;
    }

    //交换a数组中,索引和索引j处的值
    private static void exch(Comparable[] a,int i,int j){
        Comparable temp;
        temp = a[i];
        a[i]=a[j];
        a[j]=temp;

    }
}

优化后

public static Integer[] bubbleSort(Integer[] arr){
        int num = 0;
        for (int i=0;i< arr.length-1;i++){
            boolean flag = false;
            for (int j=0;j< arr.length-1-i;j++){
                if (arr[j]> arr[j+1]){
                    num = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = num;
                    flag = true;
                }
            }
            if (!flag){
                break;
            }else {
                flag = false;
            }
        }
        return arr;
    }

1.3选择排序

需求:

排序前: {4,6,8,7,9,2,10,1}

排序后: {1,2,4,5,7,8,9,10}

排序原理:

​ 1.每一次遍历的过程中,都假定第一个索引处的元素是最小值,和其他索引处的值依次进行比较,如果当前索引处的值大于其他某个索引处的值,则假定其他某个索引出的值为最小值,最后可以找到最小值所在的索引

​ 2.交换第一个索引处和最小值所在的索引处的值

​ 时间复杂度为(n^2)

类名Selection()
构造方法Selection():创建Selection对象
成员方法1.public static void sort(Comparable[] v):对数组内的元素进行排序
2.private static boolean greater(Comparable v,Comparable W);判断v是否大于w
3.private static void exch(Comparable[] a,int i,intj)。交换a数组中,索引和索引j处的值

代码实现

package com.zhao.sort;

import java.util.Arrays;

public class SelectionTest {
    public static void main(String[] args) {
        Integer[] arr = {5,4,2,3,6,1};
        Selection.sort(arr);

        System.out.println(Arrays.toString(arr));

    }
}

//选择排序
class Selection{
    //对数组内的元素进行排序
    public static void sort(Comparable[] v){
        for (int i=0;i<= v.length-2;i++){
            //定义一一个变量,记录最小元素所在的索引,默认为参与选择排序的第一个元素所在的位置
            int minIndex = i;
            for (int j=i+1;j<=v.length-1;j++){
                if (greater(v[minIndex],v[j])){
                    minIndex = j;
                }
            }
            exch(v,i,minIndex);
        }

    }
    //判断v是否大于w
    private static boolean greater(Comparable v,Comparable w){
        return v.compareTo(w) > 0;
    }

    //交换a数组中,索引和索引j处的值
    private static void exch(Comparable[] a,int i,int j){
        Comparable temp;
        temp = a[i];
        a[i]=a[j];
        a[j]=temp;

    }
}

优化后:

public static void selectionSort(Integer[] arr){
        for (int i=0 ;i< arr.length-1;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;
            }
        }
    }

1.4 插入排序

插入排序( Insertion sort )是一种简单直观且稳定的排序算法。

​ 插入排序的工作方式非常像人们排序一手扑克牌一样。开始时,我们的左手为空并且桌子上的牌面朝下。然后,我们每次从桌子上拿走一张牌并将它插入左手中正确的位置。为了找到-张牌的正确位置,我们从右到左将它与已在手中的每张牌进行比较。

排序原理

​ 1.把所有的元素分为两组,已经排序的和未排序的;

​ 2.找到未排序的组中的第一个元素 ,向已经排序的组中进行插入;

​ 3.倒叙遍历已经排序的元素,依次和待插入的元素进行比较,直到找到一个元素小于等于待插入元素,那么就把待插入元素放到这个位置,其他的元素向后移动一位;

类名Insertion()
构造方法Insertion():创建Insertion对象
成员方法1.public static void sort(Comparable[] v):对数组内的元素进行排序
2.private static boolean greater(Comparable v,Comparable W);判断v是否大于w
3.private static void exch(Comparable[] a,int i,intj)。交换a数组中,索引和索引j处的值

代码实现:

package com.zhao.sort;

import java.util.Arrays;

public class InsertionTest {
    public static void main(String[] args) {
        Integer[] arr = {5,4,2,3,6,1};
        Insertion.sort(arr);

        System.out.println(Arrays.toString(arr));

    }
}

//插入排序
class Insertion{
    //对数组内的元素进行排序
    public static void sort(Comparable[] v){
        for (int i =1;i< v.length;i++){
            for (int j =i;j>0;j--){
                //比较索引j处的值和索引j-1处的值,如果索引j-1的值大,则交换数据
                if (greater(v[j-1],v[j])){
                    exch(v,j-1,j);
                }else{
                    break;
                }
            }
        }

    }
    //判断v是否大于w
    private static boolean greater(Comparable v,Comparable w){
        return v.compareTo(w) > 0;
    }

    //交换a数组中,索引i和索引j处的值
    private static void exch(Comparable[] a,int i,int j){
        Comparable temp;
        temp = a[i];
        a[i]=a[j];
        a[j]=temp;

    }
}

二、高级排序

2.1希尔排序

排序原理:

1.选定一个增长量h ,按照增长量h作为数据分组的依据,对数据进行分组;

2.对分好组的每一组数据完成插入排序;

3.减小增长量,最小减为1 ,重复第二步操作。

在这里插入图片描述

增长量h的确定:增长量h的值每一固定的规则,我们这里采用以下规则:

int h=1
while(h<数组长度/2){
    h=2h+1;
}
//循环结束后我们就可以确定h的最大值
h的减小格则为:
    h=h/2
类名Shell()
构造方法Shell():创建Bubble对象
成员方法1.public static void sort(Comparable[] v):对数组内的元素进行排序
2.private static boolean greater(Comparable v,Comparable W);判断v是否大于w
3.private static void exch(Comparable[] a,int i,intj)。交换a数组中,索引和索引j处的值

代码实现

package com.zhao.sort;

import java.util.Arrays;

public class ShellTest {
    public static void main(String[] args) {
        Integer[] arr = {5,4,2,3,6,1,5,10,55,66};
        Bubble.sort(arr);

        System.out.println(Arrays.toString(arr));

    }
}

//希尔排序
class Shell{
    //对数组内的元素进行排序
    public static void sort(Comparable[] v){
        //1.根据数组v的长度,确定增长量h的初始值
        int h =1;
        while (h<v.length/2){
            h= h*2+1;
        }
        //2.希尔排序
        while(h>=1){
            //排序
            //2.1 找到待插入的元素
            for (int i = h;i<v.length;i++){
                //2.2把待插入的元素插入到有序数列中
                for (int j=i;j>=h;j=j-h){
                    //待插入的元素是a[j],比较a[j]和[j-h]
                    if (greater(v[j-h],v[j])){
                        //交换元素
                        exch(v,j-h,j);
                    }else{
                        //待插人元素已经找到了合适的位置,结束循环;
                        break;
                    }


                }
            }
            h /= 2;
        }

    }
    //判断v是否大于w
    private static boolean greater(Comparable v,Comparable w){
        return v.compareTo(w) > 0;
    }

    //交换a数组中,索引i和索引j处的值
    private static void exch(Comparable[] a,int i,int j){
        Comparable temp;
        temp = a[i];
        a[i]=a[j];
        a[j]=temp;

    }
}

2.2 快速排序

快速排序(Quicksort) 是对冒泡排序的一种改进。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列.

在这里插入图片描述

代码实现

package com.zhao.sort;

import java.util.Arrays;

public class QuickSort {
    public static void main(String[] args) {
        int[] arr = {1,66,85,2,3,5,6,-4};
        sort(arr,0, arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    public static void sort(int[] arr,int left,int right){
        int l_index = left;//左下标
        int r_index = right;//右下标
        //中轴值
        int pivot = arr[(left+right)/2];
        int temp = 0;//临时变量,作为交换时使用

        //while循环的目的是让比pivot小的放到左边,大的放在右边
        while (l_index < r_index){
            while (arr[l_index] < pivot){//在pivot的左边找,找到大于pivot值,才退出
                l_index += 1;
            }
            while (arr[r_index] > pivot){//在pivot的右边找,找到小于pivot值,才退出
                r_index -= 1;
            }
            if (l_index >= r_index){
                break;
            }

            //交换
            temp = arr[l_index];
            arr[l_index] = arr[r_index];
            arr[r_index] = temp;

            //如果交换完后,发现这个arr[l_index] == pivot值相等r--,前移
            if (arr[l_index] == pivot){
                r_index -= 1;
            }

            //如果交换完后,发现这个arr[r_index] == pivot值相等,后移
            if (arr[r_index] == pivot){
                l_index += 1;
            }
        }

        if (l_index == r_index){
            l_index += 1;
            r_index -= 1;
        }

        if (left < r_index){
            sort(arr, left, r_index);
        }
        if (right > l_index){
            sort(arr,l_index,right);
        }
    }
}

2.3归并排序

归并排序(MERGE- SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide- and conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案修补在一起,即分而治之)。
在这里插入图片描述

代码实现

package com.zhao.sort;

import java.util.Arrays;

public class MergetSort {
    public static void main(String[] args) {
        int[] arr = {1,5,8,3,2,9,10};
        int[] temp = new int[arr.length];
        mergeSort(arr,0,arr.length-1,temp);
        System.out.println(Arrays.toString(arr));

    }

    //分 + 和方法
    public 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);

        }
    }


    /**
     * 合并
     * @param arr   排序的原始数组
     * @param left  左边有序序列的初始索引
     * @param mid   中间索引
     * @param right 右边索引
     * @param temp  中转数组
     */
    public static void merge(int[] arr,int left,int mid,int right , int[] temp){
        int i = left;//初始化i, 左边有序序列的初始索引
        int j = mid+1;//初始化j,右边有序序列的初始索引
        int t = 0;// 指向temp数组的当前索引
        //(-)
        // 先把左右两边(有序)的数据按照规则填充到temp数组
        //直到左右两边的有序序列,有一边处理完毕为止
        while (i <= mid && j <= right){
            if (arr[i] <= arr[j]){
                temp[t] = arr[i];
                t += 1;
                i += 1;
            }else {
                temp[t] = arr[j];
                t += 1;
                j += 1;
            }
        }

        //(二)
        //把有剩余数据的一边的数据依次全部填充到temp
        while (i <= mid){
            temp[t] = arr[i];
            t += 1;
            i += 1;
        }
        while (j <= right){
            temp[t] = arr[j];
            t += 1;
            j += 1;
        }

        //(三)
        //将temp数组的元素拷贝到arr
        //并不是每次都拷贝所有
        t = 0;
        int tempLeft = left;
        while (tempLeft <= right){
            arr[tempLeft] = temp[t];
            t += 1;
            tempLeft += 1;
        }

    }
}

2.4基数排序

基数排序(桶排序)介绍:

  • 基数排序(radixsort) 属于“分配式排序”(distributionsort) ,又称“桶子法”(bucket sort)或binsort, 顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用
  • 基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法
  • 基数排序(Radix Sort)是桶排序的扩展
  • 基数排序是1887年赫尔曼何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较.

基数排序的说明:

  • 基数排序是对传统桶排序的扩展,速度很快
  • 基数排序是经典的空间换时间的方式,占用内存很大,当对海量数据排序时,容易造成OutOfMemoryError。
  • 基数排序时稳定的。[注:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[i], 且r[i]r[j]之前, 而在排序后的序列中,r[i]仍在r[j]之 前,则称这种排序算法是稳定的;否则称为不稳定的]
  • 有负数的数组,我们不用基数排序来进行排序

代码实现

package com.zhao.sort;

import java.util.Arrays;

public class RadixSort {
    public static void main(String[] args) {
        int[] arr = {122,56,12,89,563,555};
        radixSort(arr);

    }
    public static void radixSort(int[] arr){
        //1.得到数组中最大的数的位数
        int max = arr[0];//假设第一个数就是最大数
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] > max){
                max = arr[i];
            }
        }
        //得到最大数是几位数
        int maxLength = (max+"").length();
        //定义一个二维数组,表示10个桶,每个桶就是一个二维数组
        //1.二维数组包含10个一维数组
        //2.为了防止在放入数的时候,数据溢出,则每个一维数组(桶),大小定为arr。length
        //3.明确,基数排序是使用空间换时间的经典算法
        int[][] bucket = new int[10][arr.length];
        //为了记录每个桶中,实际存放了多少个数据,我们定义一个一维数组来记录各个桶的每次放入的数据个数
        // 比如: bucketElementCounts[0] ,记录的就是bucket[0] 桶的放入数据个数
        int[] bucketCount = new int[10];


        for (int i = 0,n = 1; i < maxLength; i++,n *= 10) {
            //针对每个元素的对应位进行排序
            for (int j = 0; j < arr.length; j++) {
                int digitOfElement = (arr[j]/n)%10;//取出每一个元素的对应位的值
                //放入相应的桶中
                bucket[digitOfElement][bucketCount[digitOfElement]] = arr[j];
                bucketCount[digitOfElement]++;
            }
            //取出数据,放入到原数组
            int index = 0;
            //遍历每一个桶,并将桶中的数据,放入到原数组
            for (int k =0 ; k<bucketCount.length ; k++){
                //如果桶中有数
                if (bucketCount[k] != 0){
                    //循环该桶及第k个一维数组
                    for (int l = 0; l < bucketCount[k]; l++) {
                        //取出数据放入到arr
                        arr[index++] = bucket[k][l];
                    }
                }
                //第i+1轮处理后,需要将每个bucketElementCounts[k] = 0 !!!
                bucketCount[k] = 0;

            }
            System.out.println("第"+(i+1)+"次,对每个位的排序处理"+ Arrays.toString(arr));
        }

    }
}

2.5堆排序

堆排序基本介绍

  • 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为0(nlogn),它也是不稳定排序。
  • 堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆,注意:没有要求结点的左孩子的值和右孩子的值的大小关系。>
    • 大顶堆特点:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]
  • 每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆
    • 小顶堆特点:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2]
  • 一般升序采用大顶堆,降序采用小顶堆

堆排序的基本思想是:

  1. 将待排序序列构造成一个大项堆
  2. 此时,整个序列的最大值就是堆项的根节点。
  3. 将其与末尾元素进行交换,此时末尾就为最大值。
  4. 然后将剩余n-1个元素重新构造成一-个堆, 这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

可以看到在构建大项堆的过程中,元素的个数逐渐减少,最后就得到一个有序序列了.

代码实现:

package com.zhao.tree;

import java.util.Arrays;

public class HeapSort {
    public static void main(String[] args) {
        int[] arr = {122,56,12,89,563,555};
        heapSort(arr);
        System.out.println(Arrays.toString(arr));
        heapSort2(arr);
        System.out.println(Arrays.toString(arr));
    }

    //堆排序升序
    public static void heapSort(int[] arr){
        int temp = 0;
        System.out.println("升序堆排序");

        //1.将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆
        for (int i = arr.length/2-1; i >= 0 ; i--) {
            adjustHeap(arr,i, arr.length);
        }
        //2.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
        //3.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
        for (int j = arr.length-1 ; j > 0 ; j--) {
            //交换
            temp = arr[j];
            arr[j] = arr[0];
            arr[0] = temp;
            adjustHeap(arr,0,j);
        }

    }
    //堆排序降序
    public static void heapSort2(int[] arr){
        int temp = 0;
        System.out.println("降序堆排序");
        //1.将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆
        for (int i = arr.length/2-1; i >= 0 ; i--) {
            adjust(arr,i, arr.length);
        }
        //2.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
        //3.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
        for (int j = arr.length-1 ; j > 0 ; j--) {
            //交换
            temp = arr[j];
            arr[j] = arr[0];
            arr[0] = temp;
            adjust(arr,0,j);
        }

    }

    /**
     * 将一个数组(二叉树),调整成一个大顶堆
     * @param arr  待调整的数组
     * @param i    表示非叶子节点在数组中的索引
     * @param length 表示对多少个元素进行调整,length逐渐减少
     */
    public static void adjustHeap(int[] arr,int i ,int length){
        int temp = arr[i];//取出当前元素的值,保存在临时变量
        //开始调整
        //1. j = i*2+1  j是i节点的左子节点
        for (int j = i*2+1; j < length ; j = j*2+1) {
            if (j+1 < length && arr[j]<arr[j+1]){//左子节点的值小于右子节点的值
                j++; // j 指向右子节点
            }
            if (arr[j] > temp){//子节点比父节点大
                arr[i] = arr[j];//把大的值赋给当前节点
                i = j; // i 指向 j
            }else {
                break;
            }
        }
        //当for循环结束后,我们已经将以i为父结点的树的最大值,放在了最顶(局部)
        arr[i] = temp;//循环结束把较小的值付给子节点
    }


    /**
     * 将一个数组(二叉树),调整成一个小顶堆
     * @param arr  待调整的数组
     * @param i    表示非叶子节点在数组中的索引
     * @param length 表示对多少个元素进行调整,length逐渐减少
     */
    public static void adjust(int[] arr,int i ,int length){
        int temp = arr[i];
        for (int j = i*2+1; j < length; j=j*2+1) {
            if (j+1<length && arr[j] > arr[j+1]){//左子节点的值大于右子节点的值
                j++;
            }
            if (arr[j]<temp){//子节点比父节点小
                arr[i] = arr[j];//把大的值赋给当前节点
                i = j; // i 指向 j
            }else {
                break;
            }
        }
        //当for循环结束后,我们已经将以i为父结点的树的最小值,放在了最顶(局部)
        arr[i] = temp;//循环结束把较大的值付给子节点
    }
}


常用排序算法的比较

在这里插入图片描述

目 录 摘 要 1 关键词 1 Abstract 1 Keywords 1 前 言 2 1 系统技术及运行环境 3 1.1 JSP技术简介 3 1.2 JAVABEAN技术简介 4 1.3 JDBC技术简介 4 1.4 TOMCAT技术简介 5 1.5运行环境 5 2 需求分析 6 2.1 编写目的 6 2.2 任务目标 6 2.2.1基本性能 6 2.2.2开发目标 7 2.2.3 应用目标 7 2.3选择编程语言 7 2.3.1 JSP与ASP的比较 7 2.3.2 JSP的特点与优点 8 3系统设计 10 3.1系统设计思想 10 3.1.1 网上论坛系统说明 10 3.1.2 网上论坛系统总体分析 10 3.2 数据库设计思想 11 3.3 各单元模块设计 12 3.3.1用户注册登陆功能 12 3.3.2会员发贴与回复功能 13 3.3.3管理员管理帖子与用户管理功能 15 4 编码实现 16 4.1 功能总体说明 16 4.1.1 功能总体说明 16 4.1.2主要功能流程 17 4.2各个功能模块的实现 17 4.2.1数据库的连接 17 4.2.2用户登陆与注册模块的实现 18 4.2.3分页显示的功能实现 23 4.2.4 发表与回复功能模块实现 24 4.2.5后台管理模块的实现 27 5 系统测试 30 总 结 31 参考文献 33 致 谢 33 4.2.1数据库的连接 出于安全性的考虑,我们将与数据库的连接,单独写出来并进行编译,也就是数据库连接的javabean文件,编译出来的.class文件是无法被修改的只能通过源文件进行修改,我们在JSP页面中只用直接调用该方法即可,在本系统中我们将其命名为DBConMgr.java 关键代码如下: import java.sql.*; public class DBConMgr { private String driverName="com.mysql.jdbc.Driver"; //驱动程序名 private String userName="root"; //数据库用户名 private String userPwd="123456"; //密码 private String url= "jdbc:mysql://localhost:3306/bbs"; //连接字符串 private Connection conn=null; //数据库连接对象 public Statement sm=null; //数据库语句对象 public void ConnectDB(){ try { Class.forName( driverName); conn = DriverManager.getConnection(url, userName , userPwd); sm=conn.createStatement(); System.out.println("------------------数据库连接成功!"); } catch(Exception e) { e.printStackTrace(); System.out.println("------------------数据库连接失败!"); } } public void CloseDB(){ try { if (sm != null) { sm.close(); } conn.close(); } catch (SQLException SqlE) { SqlE.printStackTrace(); System.out.println("-------------------数据库关闭失败!"); } } }
<think>首先,用户查询的是“用JavaScript实现快速排序代码并查看其图解”。所以我需要提供清晰的JavaScript代码和一个图解来解释快速排序的工作原理。 从系统指令: - 所有行内数学表达式使用$...$格式。但快速排序不涉及数学表达式,所以可能不需要。 - 独立公式使用$$...$$格式,但这里没有公式。 - LaTeX语法正确:确保任何数学内容正确。 - 使用中文回答。 - 生成相关问题:在回答末尾添加相关问题。 - 引用的段落末尾添加引用标识:例如[^1]。 用户提供了引用:[1], [2], [3]: - [1]:JavaScript经典排序方法图解代码实现,包括冒泡排序和提到快速排序O(nlgn)。 - [2]:双指针法实现快速排序,解释基本思想。 - [3]:图解快速排序算法,不超过18代码Python和JavaScript实现,并提供了一个JavaScript代码示例。 我应该基于这些引用构建我的回答。用户指定了“JavaScript实现快速排序代码图解”,所以我需要整合信息和提供图解。 结构我的回答: 1. **解释快速排序**:简要介绍快速排序的概念,参考[2]中的描述——“分而治之”的思想。 2. **提供JavaScript代码**:使用[3]中的代码作为示例,因为它是JavaScript实现。我可以复制或适配它。 - 代码在[3]中:quickSortASC函数。 3. **添加图解**:既然用户要求图解,我需要描述或引用一个图解。引用[1]提到“图解”,引用[3]说“图解快速排序算法”,所以我应该创建一个简单的文本描述或步骤图解。 - 由于文本回答,我可以描述关键步骤,类似于图解。 4. **确保回答真实可靠**:基于标准算法知识。 5. **格式**: - 代码块使用Markdown格式:```javascript ... ``` - 解释清晰。 6. **结尾添加相关问题**:根据指令,“生成相关问题”,并在最后以“§§相关问题§§”开始列表。 回答步骤: - 开头解释快速排序。 - 提供JavaScript代码示例。 - 描述图解(步骤可视化)。 - 末尾添加相关问题。 JavaScript代码从[3]: ```javascript function swap_arr(arr, i, j) { var tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } function quickSortASC(nums, start, end) { if (start < end) { var i = start; var j = end; var poit = nums[start]; // pivot element while (i < j) { while (i < j && poit <= nums[j]) { j--; } swap_arr(nums, i, j); while (i < j && poit >= nums[i]) { i++; } swap_arr(nums, i, j); } quickSortASC(nums, start, i); quickSortASC(nums, i + 1, end); } } // 示例用法 num_arr = [23, 34, 544, 234, 17, 554, 78, 656]; quickSortASC(num_arr, 0, 7); console.log(num_arr); // 输出排序后的数组 ``` 图解描述: - 我可以描述分治过程: 1. 选择 pivot(例如数组第一个元素)。 2. Partitioning:使用双指针i和j,从两端向中间移动,交换元素使得小于pivot的在一个子数组,于的在另一个。 3. 递归排序子数组。 - 提供一个小例子,比如排序 [3, 1, 4, 2]。 相关问题: - 基于主题,如: 1. 快速排序的时间复杂度是多少? 2. 如何优化快速排序? 3. 快速排序与其他排序算法的比较? 添加引用标识: - 在解释或代码后添加[^1], [^2], [^3] 如果直接引用。 最终回答结构: 1. 介绍快速排序。 2. JavaScript代码实现。 3. 图解步骤描述。 4. 相关问题。 </think>以下是针对您查询“用JavaScript实现快速排序代码图解”的详细解答。我将结合相关引用内容,逐步解释快速排序的原理、JavaScript实现代码,并通过文字图解描述其工作过程。快速排序的核心思想是“分而治之”,通过选择基准元素(pivot)将数组分割为子数组并递归排序[^2]。 ### 1. **JavaScript实现快速排序代码** 基于引用[3]中的优化实现,这是一个完整的JavaScript代码示例(使用双指针法,代码简洁高效): ```javascript function swap_arr(arr, i, j) { var tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } function quickSort(arr, start, end) { if (start < end) { // 初始化指针和基准(pivot) var i = start; var j = end; var pivot = arr[start]; // 选择数组第一个元素作为基准 while (i < j) { // 从右向左找第一个小于pivot的元素 while (i < j && pivot <= arr[j]) { j--; } swap_arr(arr, i, j); // 从左向右找第一个于pivot的元素 while (i < j && pivot >= arr[i]) { i++; } swap_arr(arr, i, j); } // 递归排序左子数组和右子数组 quickSort(arr, start, i); quickSort(arr, i + 1, end); } return arr; } // 示例用法 var nums = [23, 34, 544, 234, 17, 554, 78, 656]; quickSort(nums, 0, nums.length - 1); console.log(nums); // 输出: [17, 23, 34, 78, 234, 544, 554, 656] ``` **代码说明**: - **`swap_arr`函数**:交换数组中两个元素的位置。 - **`quickSort`函数**: - **参数**:`arr`(待排序数组),`start`(起始索引),`end`(结束索引)。 - **基准选择**:使用数组第一个元素作为pivot(可优化为随机选择以避免最坏情况)。 - **双指针法**:`i`从左侧向右扫描,`j`从右侧向左扫描,确保左子数组元素≤pivot,右子数组元素≥pivot。 - **递归分割**:分区后递归排序左半部分(`start`到`i`)和右半部分(`i+1`到`end`)。 - **时间复杂度**:平均$O(n \log n)$,最坏$O(n^2)$(当数组已有序时)[^1]。 - **空间复杂度**:$O(\log n)$(递归栈深度)。 ### 2. **快速排序图解描述** 以下通过文字步骤图解展示快速排序对数组 `[3, 1, 4, 2]` 的排序过程(结合引用[3]的图解逻辑)。图解基于双指针分区操作: 1. **初始状态**: - 数组:<span style="color:blue;">[3]</span>, 1, 4, 2(蓝色为pivot)。 - 指针:`i=0`(左),`j=3`(右)。 2. **第一轮分区(Partitioning)**: - 步骤1:`j`从右向左扫描,找到第一个小于pivot(3)的元素2(索引3),交换位置: - 数组:2, 1, 4, <span style="color:blue;">[3]</span> - 步骤2:`i`从左向右扫描,找到第一个于pivot(3)的元素4(索引2),交换位置: - 数组:2, 1, <span style="color:blue;">[3]</span>, 4 - 步骤3:`i`和`j`相遇(i=j=2),分区结束。左子数组:`[2, 1]`;右子数组:`[4]`。 3. **递归排序左子数组 `[2, 1]`**: - 选择pivot=2(第一个元素)。 - `j`从右扫描,找到1<2,交换:数组变为1, <span style="color:blue;">[2]</span>。 - `i`和`j`相遇,递归结束。排序后左子数组:`[1, 2]`。 4. **递归排序右子数组 `[4]`**: - 单元素数组,直接返回`[4]`。 5. **最终合并**: - 左子数组 `[1, 2]` + pivot `3` + 右子数组 `[4]` → 排序结果:`[1, 2, 3, 4]`。 **图解关键点**: - **基准作用**:pivot将数组分为两个独立部分。 - **双指针移动**:确保高效分区(平均时间复杂度$O(n)$)。 - **递归终止条件**:子数组长度≤1时停止递归[^2]。 ### 3. **性能与应用** - **高效场景**:数据量排序(如前端数据处理),平均性能优于冒泡排序$O(n^2)$[^1]。 - **优化建议**:随机选择pivot或三数取中法避免最坏情况;小数组切换为插入排序。 - **实际应用**:JavaScript中常用于表格排序、数据可视化库(如D3.js)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值