常见排序查找算法
Posted 赵广陆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常见排序查找算法相关的知识,希望对你有一定的参考价值。
目录
- 1 数组打乱顺序
- 2 判断整数是不是2的阶次方
- 3、判断日期
- 4、面向对象思想实现篮子物品交换
- 5 二分查找
- 6 冒泡排序算法
- 7 插入排序算法
- 8 快速排序算法
- 9 希尔排序算法
- 10 归并排序算法
- 11 桶排序算法
- 12 基数排序算法
- 13 剪枝算法
- 14 回溯算法
- 15 最短路径算法
- 16 最小生成树算法
1 数组打乱顺序
数据里有1,2,3,4,5,6,7,8,9,请随机打乱顺序,生成一个新的数组(请以代码实现)
import java.util.Arrays;
//打乱数组
public class Demo1 //随机打乱
public static int[] srand(int[] a)
int[] b = new int[a.length];
for (int i = 0; i < a.length; i++)
//随机获取下标
int tmp = (int) (Math.random() * (a.length - i)); //随机数: [ 0 , a.length - i )
b[i] = a[tmp];
//将此时a[tmp]的下标移动到靠后的位置
int change = a[a.length - i - 1];
a[a.length - i - 1] = a[tmp];
a[tmp] = change;
return b;
public static void main(String[] args)
int[] a = 1, 2, 3, 4, 5, 6, 7, 8, 9;
System.out.println(Arrays.toString(srand(a)));
2 判断整数是不是2的阶次方
写出代码判断一个整数是不是2的阶次方(请代码实现,谢绝调用API方法)
import java.util.Scanner;
//判断整数是不是2的阶次方
public class Demo2
public static boolean check(int sum)
boolean flag = true;
//判断标志
while (sum > 1)
if (sum % 2 == 0)
sum = sum / 2;
else
flag = false;
break;
return flag;
public static void main(String[] args)
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个整数:");
int sum = scanner.nextInt();
System.out.println(sum + " 是不是2的阶次方:" + check(sum));
3、判断日期
假设今日是2015年3月1日,星期日,请算出13个月零6天后是星期几,距离现在多少天(请用代码实现,谢绝调用 API方法)
mport java.util.Scanner;
//算出星期几
public class Demo4
public static String[] week = "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六";
public static int i = 0;
public static int[] monthday1 = 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31;
public static int[] monthday2 = 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31;
//查看距离当前天数的差值
public static String distance(int year, int month, int day, int newMonth, int newDay)
int sum = 0; //设定初始距离天数
if (month + newMonth >= 12)
if (((year + 1) % 4 == 0 && (year + 1) % 100 != 0) || (year + 1) % 400 == 0)
sum += 366 + newDay;
for (int i = 0; i < newMonth - 12; i++)
sum += monthday1[month + i];
else
sum += 365 + newDay;
for (int i = 0; i < newMonth - 12; i++)
sum += monthday1[month + i];
else
for (int i = 0; i < newMonth; i++)
sum += monthday1[month + i];
sum += newDay;
return week[sum % 7];
public static void main(String[] args)
Scanner scanner = new Scanner(System.in);
System.out.println("请输入当前年份");
int year = scanner.nextInt();
System.out.println("请输入当前月份");
int month = scanner.nextInt();
System.out.println("请输入当前天数");
int day = scanner.nextInt();
System.out.println("请输入当前是星期几:以数字表示,如:星期天 为 0");
int index = scanner.nextInt();
System.out.println("今天是:" + year + "-" + month + "-" + day + " " +
week[index]);
System.err.println("请输入相隔月份");
int newMonth = scanner.nextInt();
System.out.println("请输入剩余天数");
int newDay = scanner.nextInt();
System.out.println("经过" + newMonth + "月" + newDay + "天后,是" +
distance(year, month, day, newMonth, newDay));
4、面向对象思想实现篮子物品交换
有两个篮子,分别为A 和 B,篮子A里装有鸡蛋,篮子B里装有苹果,请用面向对象的思想实现两个篮子里的物品交换(请用代码实现)
答:
//面向对象思想实现篮子物品交换
public class Demo5
public static void main(String[] args)
//创建篮子
Basket A = new Basket("A");
Basket B = new Basket("B");
//装载物品
A.load("鸡蛋");
B.load("苹果");
//交换物品
A.change(B);
A.show();
B.show();
class Basket
public String name; //篮子名称
private Goods goods; //篮子中所装物品
public Basket(String name)
// TODO Auto-generated constructor stub
this.name = name;
System.out.println(name + "篮子被创建");
//装物品函数
public void load(String name)
goods = new Goods(name);
System.out.println(this.name + "装载了" + name + "物品");
public void change(Basket B)
System.out.println(this.name + " 和 " + B.name + "中的物品发生了交换");
String tmp = this.goods.getName();
this.goods.setName(B.goods.getName());
B.goods.setName(tmp);
public void show()
System.out.println(this.name + "中有" + goods.getName() + "物品");
class Goods
private String name; //物品名称
public String getName()
return name;
public void setName(String name)
this.name = name;
public Goods(String name)
// TODO Auto-generated constructor stub
this.name = name;
5 二分查找
又叫折半查找,要求待查找的序列有序。每次取中间位置的值与待查关键字比较,如果中间位置的值比待查关键字大,则在前半部分循环这个查找的过程,如果中间位置的值比待查关键字小,则在后半部分循环这个查找的过程。直到查找到了为止,否则序列中没有待查的关键字。
public static int biSearch(int []array,int a)
int lo=0;
int hi=array.length-1;
int mid;
while(lo<=hi)
mid=(lo+hi)/2;
//中间位置 if(array[mid]==a) return mid+1; else if(array[mid]<a) //向右查找 lo=mid+1; else //向左查找 hi=mid-1; return -1;
6 冒泡排序算法
1)比较前后相邻的二个数据,如果前面数据大于后面的数据,就将这二个数据交换。
2)这样对数组的第 0 个数据到 N-1 个数据进行一次遍历后,最大的一个数据就“沉” 到数组第N-1 个位置。
3) N=N-1,如果 N 不为 0 就重复前面二步,否则排序完成。
public static void bubbleSort1(int [] a, int n)
int i, j;
for(i=0; i<n; i++)//表示 n 次排序过程。
for(j=1; j<n-i; j++)
if(a[j-1] > a[j])//前面的数字大于后面的数字就交换
//交换 a[j-1]和 a[j]
int temp;
temp = a[j-1];
a[j-1] = a[j];
a[j]=temp;
7 插入排序算法
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应的位置并插入。插入排序非常类似于整扑克牌。在开始摸牌时,左手是空的,牌面朝下放在桌上。接着, 一次从桌上摸起一张牌,并将它插入到左手一把牌中的正确位置上。 为了找到这张牌的正确位置,要将它与手中已有的牌从右到左地进行比较。无论什么时候,左手中的牌都是排好序的。如果输入数组已经是排好序的话,插入排序出现最佳情况,其运行时间是输入规模的一个线性函数。如果输入数组是逆序排列的,将出现最坏情况。平均
情况与最坏情况一样,其时间代价是(n2)。
public void sort(int arr[])
for(int i =1; i<arr.length;i++)
//插入的数
int insertVal = arr[i];
//被插入的位置(准备和前一个数比较)
int index = i-1;
//如果插入的数比被插入的数小
while(index>=0&&insertVal<arr[index])
//将把 arr[index] 向后移动
arr[index+1]=arr[index];
//让 index 向前移动
index--;
//把插入的数放入合适位置
arr[index+1]=insertVal;
8 快速排序算法
快速排序的原理:选择一个关键值作为基准值。比基准值小的都在左边序列(一般是无序的),比基准值大的都在右边(一般是无序的)。 一般选择序列的第一个元素。
一次循环: 从后往前比较,用基准值和最后一个值比较,如果比基准值小的交换位置,如果没有继续比较下一个,直到找到第一个比基准值小的值才交换。 找到这个值之后,又从前往后开始比较,如果有比基准值大的,交换位置,如果没有继续比较下一个,直到找到第一个比基准值大的值才交换。直到从前往后的比较索引>从后往前比较的索引,结束第一次循环,此时,对于基准值来说,左右两边就是有序的了。
public void sort(int[] a, int low, int high)
int start = low;
int end = high;
int key = a[low];
while (end > start)
//从后往前比较
while (end > start && a[end] >= key)
//如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较
end--;
if (a[end] <= key)
int temp = a[end];
a[end] = a[start];
a[start] = temp;
//从前往后比较
while (end > start && a[start] <= key)
//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置
start++;
if (a[start] >= key)
int temp = a[start];
a[start] = a[end];
a[end] = temp;
//此时第一次循环比较结束,关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,但是两边的顺序还有可能是不一样的,进行下面的递归调用
//递归
if (start > low) sort(a, low, start - 1);//左边序列。第一个索引位置到关键值索引-1
if (end < high) sort(a, end + 1, high);//右边序列。从关键值索引+1 到最后一个
9 希尔排序算法
基本思想:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序” 时,再对全体记录进行依次直接插入排序。
- 操作方法:选择一个增量序列t1, t2, …, tk,其中 ti>tj, tk=1; 2. 按增量序列个数k,对序列进行k趟排序;
- 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m的子序列,分别对各子表进行直接插入排序。仅增量因子为1时,整个序列作为一个表来处理,表长度即为整个序列的长度。
private void shellSort(int[] a)
int dk = a.length / 2;
while (dk >= 1)
ShellInsertSort(a, dk);
dk = dk / 2;
private void ShellInsertSort(int[] a, int dk)
//类似插入排序,只是插入排序增量是 1,这里增量是 dk,把 1 换成 dk 就可以了
for (int i = dk; i < a.length; i++)
if (a[i] < a[i - dk])
int j;
int x = a[i];//x 为待插入元素
a[i] = a[i - dk];
for (j = i - dk; j >= 0 && x 常见排序算法——快速排序