常用数据结构与算法实现
以下博客根据B站罗召勇老师视频:数据结构与算法基础-Java版(罗召勇)写的详细笔记
数据结构与算法基础:
数据结构与算法之基础概述
数据结构:
(一)数据结构与算法之数组
(二)数组结构与算法之栈
(三)数据结构与算法之队列
(四)数据结构与算法之链表
(五)数据结构与算法之树结构基础
(六)数据结构与算法之二叉树大全
(七)数据结构与算法之Huffman tree(赫夫曼树 / 霍夫曼树 / 哈夫曼树 / 最优二叉树)
(八)数据结构与算法之多路查找树(2-3树、2-3-4树、B树、B+树)
(九)数据结构与算法之图结构
十大经典算法:
(一)数据结构与算法之冒泡排序(含改进版)
(二)数据结构与算法之选择排序(含改进版)
(三)数据结构与算法之插入排序(含改进版)
(四)数据结构与算法之希尔排序
(五)数据结构与算法之归并排序
(六)数据结构与算法之快速排序
(七)数据结构与算法之堆排序
(八)数据结构与算法之计数排序
(九)数据结构与算法之桶排序
(十)数据结构与算法之基数排序
基数排序概念
基数排序(Radix Sort)是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前
排序步骤:
取得数组中的最大数,并取得位数;
arr为原始数组,从最低位开始取每个位组成radix数组;
对radix进行计数排序(利用计数排序适用于小范围数的特点)
动图展示:
静图分析:
代码实现
import java.util.Arrays; public class RadixSort { public static void main(String[] args) { int[] arr = {4, 32, 457, 16, 28, 64}; radixSort(arr); // [32, 4, 64, 16, 457, 28] // [4, 16, 28, 32, 457, 64] // [4, 16, 28, 32, 64, 457] } //基数排序 public static void radixSort(int[] arr) { // 定义临时二维数组表示十个桶 int[][] temp = new int[10][arr.length]; // 定义一个一维数组,用于记录在temp中相应的数组中存放数字的数量 int[] counts = new int[10]; //存数组中最大的数字 int max = Integer.MIN_VALUE; for (int i = 0; i < arr.length; i++) { if (arr[i] > max) { max = arr[i]; } } //计算最大数字是几位数(才能知道排序次数) int maxLength = (max + "").length(); //根据最大长度的数决定比较的次数 for (int i = 0, n = 1; i < maxLength; i++, n *= 10) { //把每一个数字分别计算余数 for (int j = 0; j < arr.length; j++) { //计算余数 int ys = arr[j] / n % 10; //把当前遍历的数据放入指定的数组中 temp[ys][counts[ys]] = arr[j]; //记录数量 counts[ys]++; } //记录取的元素需要放的位置 int index = 0; //把数字取出来 for (int k = 0; k < counts.length; k++) { //记录数量的数组中,当前余数记录的数量不为0才取 if (counts[k] != 0) { //循环取出元素 for (int l = 0; l < counts[k]; l++) { //取出元素 arr[index] = temp[k][l]; //记录下一个位置 index++; } //把数量置为0 counts[k] = 0; } } //打印每次排序后的结果 System.out.println(Arrays.toString(arr)); } } }
时间复杂度
最优时间复杂度:O(n^k)
最坏时间复杂度:O(n^k)
稳定性:稳定
初看起来,基数排序的执行效率似乎好的让人无法相信,所有要做的只是把原始数据项从数组复制到链表,然后再复制回去。如果有10个数据项,则有20次复制,对每一位重复一次这个过程。假设对5位的数字排序,就需要20 * 5=100次复制。
*如果有100个数据项,那么就有200 * 5=1000次复制。复制的次数与数据项的个数成正比,即O(n)。这是我们看到的效率最高的排序算法。
不幸的是,数据项越多,就需要更长的关键字,如果数据项增加10倍,那么关键字必须增加一位(多一轮排序)。复制的次数和数据项的个数与关键字长度成正比,可以认为关键字长度是N的对数。因此在大多数情况下,基数排序的执行效率倒退为O(N*logN),和快速排序差不多