六利用代码生成器快速实现火车基础数据的维护

Posted 夏雪冬蝉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了六利用代码生成器快速实现火车基础数据的维护相关的知识,希望对你有一定的参考价值。

 

内容

完成火车基础数据管理功能:车站(车站的名称或首字母可以搜索)、车次(高铁、动车等)、车厢(车厢种类和座位数)、座位(座位类型)。

项目中增加admin控台模块

后台管理不会有注册,一般由初始管理员分配

9.3 创建admin模块,所有的代码都是从web复制

接口改为9001

admin去掉登录页面,去掉member和登录相关的拦截,去掉乘车人页面

去掉没用的HelloWorld组件,修改logo区域

项目中增加business业务模块

关于车次的维护、卖票功能。

直接复制member模块,修改配置和启动类。

快速生成车站基础数据

生成器使用:
准备一张表,写好sql执行进数据库
修改mybatis生成器配置文件生成持久层
生成前后端代码修改菜单
修改路由
管理控台的请求:/admin/xxx,这样方便针对/admin做拦截或放行给第三方调用:/api/xxx,方便针对/api做验签等操作

车站表

 drop table if exists `station`;
 create table `station` (
                            `id` bigint not null comment \'id\',
                            `name` varchar(20) not null comment \'站名\',
                            `name_pinyin` varchar(50) not null comment \'站名拼音\',
                            `name_py` varchar(50) not null comment \'站名拼音首字母\',
                            `create_time` datetime(3) comment \'新增时间\',
                            `update_time` datetime(3) comment \'修改时间\',
                            primary key (`id`),
                            unique key `name_unique` (`name`)
 ) engine=innodb default charset=utf8mb4 comment=\'车站\';
business.sql

用代码生成器生成代码。

快速生成火车基本数据

火车类型是相对比较固定的,不会变化的,可以做成枚举,如果是经常变的,可以做成数据库来维护
票价=里程*单价,不同类型的车,单价不一样,高铁就比动车贵,同时单价不固定不变的,是阶梯单价,比如100公里内是0.4元/公里,100公里到500公里是0.3元每公里。

 

2021-10-21java:六千字快速复习七种常用排序

一、插入排序

1.原理

 将整个区间分为两个区间:1.有序区间  2.无序区间,每次将无序区间的第一个元素,在有序区间的合适位置插入.

2.代码实现

   public static void insertSort(int[] array){
       //有序区间[0,i)
       //无序区间[i,array.length)
       for(int i = 1; i < array.length;i++){
           int v = array[i];//无序区间第一个数
           int j = i-1;//有序区间最后一个下标
           for(; j >= 0 && array[j] > v;j--){
               array[j+1] = array[j];
           }
           //如果不交换此时下标在i-1
           array[j+1] = v;
       }
   }
时间复杂度为O(N^2) ;空间复杂度为O(1)
稳定性 : 稳定排序;  如果array[j] > v换成array[j] >=  v就变成不稳地的了.
特点: 1.数组越短,速度越快
      2.数组越接近有序,速度越快

二、希尔排序

1.原理

进阶版本的插入排序,先分组,再针对每个组进行排序,逐渐缩小组的个数,最终整个数组就有序了.

2.代码实现

    public static void shellSort(int[] arr){
        int gap = arr.length / 2;//将数组分为gap组
        while (gap > 1 ){
        //传入组数和数组,带组数的插入排序
            insertSortGap(arr,gap);
            gap = gap / 2;
        }
        insertSortGap(arr,1);
    }

    private static void insertSortGap(int[] arr, int gap) {
    //[0,i)为已排序区间;[i,arr.length)为未排序区间
        for(int i = gap ;i < arr.length;i++){
            int v = arr[i];
            int cur = i - gap;
            for( ; cur >= 0&& arr[cur]> v ;cur -= gap){
                arr[cur+gap] = arr[cur];
            }
            arr[cur + gap] = v;
        }
    }
时间复杂度为O(N^1.3);空间复杂度为O(1)
时间复杂度最好为O(N),最坏为O(N^2);
特点:插入排序的优化版
稳定性 : 不稳定排序

三、选择排序

1.原理

基于打擂台的方式:选数组首元素为擂主,循环遍历数组剩余元素,如果发现比擂主小的元素,就交换两个数.
遍历完成后让擂主加一,重复前面的动作.

2.代码实现

    public static void selectSort(int[] arr){
        for(int bound  = 0; bound < arr.length; bound++) {
            //bound 位置元素作为擂主,循环进行比较
            //如果打擂成功就和擂主交换
            for(int cur = bound + 1 ; cur < arr.length; cur++) {
                if(arr[bound] > arr[cur]){
                    int tmp = arr[bound];
                    arr[bound] = arr[cur];
                    arr[cur] = tmp ;
                }
            }
        }
    }
时间复杂度:O(N^2) ;空间复杂度:O(1);
稳定性 : 不稳定排序

四、堆排序

1.原理

 升序排列:将数组建一个大堆,然后将堆顶元素和堆底元素交换,重新生成一个大堆,并且将堆的大小减一,每一次循环
 都会让数组的最后一个元素是较大者,重复这个过程就实现了堆排序.  数组就是升序.

2.代码实现

    public static void heapSort(int[] arr){
        //第一步先将传入的数组创建成一个大堆
        createHeap(arr);
        //循环将堆顶元素与堆底元素交换,并且调整堆
        //当堆中是剩一个元素的时候也就不用循环了,所以少循环一次 -1
        for(int i = 0 ;i < arr.length -1 ;i ++){
                //交换堆顶和堆底元素
            //堆顶下标为0 ;堆底下标为arr.length - i -1
            swap(arr , 0 ,arr.length - i -1 );
            //交换完成再进行向下调整堆; 让堆的大小每次小 1
            shiftDown(arr , arr.length - i -1 , 0 );
        }
    }

    private static void shiftDown(int[] arr, int heapLength, int index) {
        int parent = index;
        int child = 2 * parent + 1;
        while( child < heapLength){
            //判断parent左右子树较大者
            if( child + 1 < heapLength && arr[child + 1] > arr[child]){
                child = child + 1;
            }
            //判断孩子是否大于,如果大于交换,否则满足大堆直接break
            if( arr[child] > arr[parent]){
                swap(arr, child ,parent);
            }else{
                break;
            }
            parent = child;
            child = 2 * parent + 1;
        }
    }

    private static void createHeap(int[] arr) {
        int cur  = (arr.length - 1 - 1) / 2 ;
        for( int i = cur ; i >= 0 ;i--){
            shiftDown(arr, arr.length, i);
        }
    }

    private static void swap(int[] arr, int i, int j) {
        int tmp =  arr[i];
        arr[i] = arr[j];
        arr[j] = tmp ;
    }
时间复杂度:O(N*log(N)) ;空间复杂度:O(1);
稳定性 : 不稳定排序

五、冒泡排序

1.原理

 升序排列:将一个无序的区间相邻进行比较,较大的放在后面,循环比较,一次循环可以把最大的放在数组最后,下一次
 循环可以将较大者放到次后位置,循环N次就得到了一个升序数组.

2.代码实现

    public static  void bubbleSort(int[] arr) {
        //循环 i 次
        for(int i = 0 ; i < arr.length ;i++) {
            //每循环一次会确定一个较大值
            //注意数组下标越界bound + 1 < arr.length - i
            for(int bound = 0 ;bound + 1 < arr.length - i ;bound++){
                if(arr[bound + 1] < arr[bound]){
                    int tmp = arr[bound];
                    arr[bound] = arr[bound + 1];
                    arr[bound + 1 ] = tmp;
                }
            }
        }
    }

时间复杂度:O(N^2) ;空间复杂度:O(1);
稳定性 : 稳定排序

六、快速排序

1.原理

 升序排列:1.在待排数组中选取一个数作为基准值(一般选最左侧或最右侧作为基准值;
         2.比基准值大的放在基准值的右边,比基准值小的放在基准值的左边
         3.在递归排序基准值的左边,递归基准值的右边

2.代码实现

递归版本

    public static void quickSort(int[] arr) {
        //借助helper方法进行递归
        //为了代码简单设置成前闭后闭区间[left,right]
        quickSortHelper(arr ,0 ,arr.length - 1);

    }

    private static void quickSortHelper(int[] arr, int left, int right) {
        //判断数组元素有几个,如果有0个或者1个就无需排序,直接return;
        if(left >= right){
            return ;
        }
        //通过partition对数组进行分区左侧为小于基准值,右侧为大于基准值
        //index 为整理后left和right重合的位置
        int index = partition(arr ,left ,right);
        quickSortHelper(arr ,left , index - 1);
        quickSortHelper(arr , index + 1,right);
    }

    private static int partition(int[] arr, int left, int right) {
        int i = left ;
        int j = right ;
        int base = arr[right];  //将数组最后一个元素设为基准值
        //left < right 说明数组还没判断完
        while( i < j){
            while ( i < j && arr[i] <= base){
                i++ ;
                //循环结束后,要么i和j重回,要么i下标是一个比base值大的数
            }
            while ( i < j && arr[j] >= base){
                j-- ;
                //循环结束要么j和i重合,要么j下标是一个比base小的数
            }
            //交换i和j下标的元素
            swap(arr,i ,j);
        }
        //循环结束要将i或j(i和j此时在同一位置)位置的元素和right(基准值)元素进行交换
        swap(arr, i , right);
        //返回基准值位置
        return  i;
    }
    
    private static void swap(int[] arr, int i, int j) {
        int tmp =  arr[i];
        arr[i] = arr[j];
        arr[j] = tmp ;
    }
时间复杂度:O(N*log(N)) ;空间复杂度:O(log(N))主要是因为递归;
稳定性 : 不稳定排序

非递归版本

    public static void quickSortByLoop(int[] arr) {
        //通过栈来模拟实现递归
        Stack<Integer> stack = new Stack<>();
        //将数组左右位置下标入栈
        stack.push(arr.length - 1);
        stack.push(0);
        while (!stack.empty()){
            //出栈顺序和入栈顺序相反
            int left = stack.pop();
            int right = stack.pop();
            //如果左右区间之间只有一个数证明已经有序 直接进行下一次循环
            if( left >= right){
                continue ;
            }
            int index = partition(arr , left ,right);
            //排序后的右区间[ index + 1 ,right]
            stack.push(right);
            stack.push(index + 1);
            //排序后的左区间[left ,index - 1]
            stack.push(index - 1);
            stack.push(left);
        }
    }
    
    private static int partition(int[] arr, int left, int right) {
        int i = left ;
        int j = right ;
        int base = arr[right];  //将数组最后一个元素设为基准值
        //left < right 说明数组还没判断完
        while( i < j){
            while ( i < j && arr[i] <= base){
                i++ ;
                //循环结束后,要么i和j重回,要么i下标是一个比base值大的数
            }
            while ( i < j && arr[j] >= base){
                j-- ;
                //循环结束要么j和i重合,要么j下标是一个比base小的数
            }
            //交换i和j下标的元素
            swap(arr,i ,j);
        }
        //循环结束要将i或j(i和j此时在同一位置)位置的元素和right(基准值)元素进行交换
        swap(arr, i , right);
        //返回基准值位置
        return  i;
    }

    private static void swap(int[] arr, int i, int j) {
        int tmp =  arr[i];
        arr[i] = arr[j];
        arr[j] = tmp ;
    }
时间复杂度:O(N*log(N)) ;空间复杂度:O(log(N))
稳定性 : 不稳定排序

七、归并排序

1.原理

 升序排列:将数组分成若干个子数组,若子数组仅剩一个元素那么他就是有序的,然后将这些已有的子序列合并,得到
 一个有序的数列.而将两个有序表合成一个有序表就是"二路归并".

2.代码实现

递归实现

      public static void mergeSort(int[] arr){
        //创建一个helper方法帮助完成递归
        mergeSortHelper(arr ,0 ,arr.length);
    }

    private static void mergeSortHelper(int[] arr, int low, int high) {
        if( high - low <= 1){
            return;
        }
        //求出中间值
        int  mid = (low + high) / 2;
        //这个递归执行完 [low,mid)就已经排序好了
        mergeSortHelper(arr,low ,mid);
        //这个递归执行完[mid,high)就已经排序好了
        mergeSortHelper(arr,mid , high);
        //对[low, high)进行排序
        merge(arr ,low ,mid ,high);
    }

    private static void merge(int[] arr, int low, int mid, int high) {
        int[] output = new int[high - low];
        int cur1 = low;
        int cur2 = mid;
        //记录output数组存放了多少元素
        int outputIndex = 0 ;
        while (cur1 < mid && cur2 < high){
            //这里写成 > 才能保证稳定性
            if(arr[cur1] > arr[cur2]){
                output[outputIndex] = arr[cur2];
                outputIndex++;
                cur2 ++;
            }else {
                output[outputIndex] = arr[cur1];
                outputIndex ++;
                cur1 ++;
            }
        }
        //上面循环结束不是cur1到mid就是cur2到high
        //再写两个循环将剩余的元素写入output数组中
        while (cur1 < mid){
            output[outputIndex] = arr[cur1];
            outputIndex ++;
            cur1 ++;
        }
        while (cur2 < high){
            output[outputIndex] = arr[cur2];
            outputIndex ++;
            cur2 ++;
        }
        //将output数组中的元素放回arr数组
        for(int i = 0 ;i < high - low ;i ++){
            arr[low + i ] = output[ i];
        }
    }

非递归实现

    public static void mergeSortByLoop(int[] arr) {
       //定义一个gap变量进行分组
        for (int gap = 1 ; gap < arr.length;gap *= 2){
            for(int i = 0 ;i < arr.length ;i = i + 2 * gap){
                int low = i ;
                int mid = i + gap;
                int high = i  + 2* gap;
                if(mid > arr.length){
                    mid  = arr.length;
                }
                if(high > arr.length){
                    high = arr.length;
                }
                merge(arr , low , mid ,high);
            }
        }
    }

    private static void merge(int[] arr, int low, int mid, int high) {
        int[] output = new int[high - low];
        int cur1 = low;
        int cur2 = mid;
        //记录output数组存放了多少元素
        int outputIndex = 0 ;
        while (cur1 < mid && cur2 < high){
            //这里写成 > 才能保证稳定性
            if(arr[cur1] > arr[cur2]){
                output[outputIndex] = arr[cur2];
                outputIndex++;
                cur2 ++;
            }else {
                output[outputIndex] = arr[cur1];
                outputIndex ++;
                cur1 ++;
            }
        }
        //上面循环结束不是cur1到mid就是cur2到high
        //再写两个循环将剩余的元素写入output数组中
        while (cur1 < mid){
            output[outputIndex] = arr[cur1];
            outputIndex ++;
            cur1 ++;
        }
        while (cur2 < high){
            output[outputIndex] = arr[cur2];
            outputIndex ++;
            cur2 ++;
        }
        //将output数组中的元素放回arr数组
        for(int i = 0 ;i < high - low 以上是关于六利用代码生成器快速实现火车基础数据的维护的主要内容,如果未能解决你的问题,请参考以下文章

MySQL利用Navicat导出数据字典

快速生成 tabBar.items 的需求计数

六千字快速复习七种常用排序

六千字快速复习七种常用排序

2021-10-21java:六千字快速复习七种常用排序

Python基础 ( 六 ) —— 迭代器和生成器