Java 7大常見排序方法實例詳解
更新時間:2017年04月19日 16:17:28 投稿:wbb
這篇文章主要通過實例介紹了Java中常用的7種排序方法,需要的朋友可以參考下
直接插入排序
<code class="language-java hljs ">import java.util.HashMap;
public class InsertSort {
private static int contrastCount = 0;//對比次數(shù)
private static int swapCount = 0;//交換次數(shù)
public static void main(String[] args) {
System.out.println("直接插入排序:\n 假設前面的序列都已經(jīng)排序好了,把后面未排序的數(shù)往已排好序的序列內(nèi)插入,時間復雜度O(n^2),空間復雜度O(1),穩(wěn)定排序");
HashMap<integer,integer> hashMap = new HashMap<integer,integer>();
init(hashMap);//初始化
System.out.println("初始序列為:");
print(hashMap, 0);//打印
insert(hashMap);//排序
}
/**
* 初始化函數(shù)
* @param hashMap
*/
private static void init(HashMap<integer, integer=""> hashMap) {
hashMap.put(0, null);//第一位置空
hashMap.put(1, 0);
hashMap.put(2, 5);
hashMap.put(3, 11);
hashMap.put(4, 12);
hashMap.put(5, 13);
hashMap.put(6, 4);
hashMap.put(7, 1);
hashMap.put(8, 5);
hashMap.put(9, 8);
hashMap.put(10, 6);
hashMap.put(11, 4);
hashMap.put(12, 8);
}
/**
* 進行插入排序
* @param hashMap 待排序的表
*/
private static void insert(HashMap<integer, integer=""> hashMap){
System.out.println("開始插入排序:");
int i,j;
//排序開始時間
long start = System.currentTimeMillis();
for(i=2; i<hashmap.size(); author="" code="" contrastcount="0;//對比次數(shù)" count="1;//只為統(tǒng)計執(zhí)行次數(shù)" d="1,時間復雜度o(n^1.3),空間復雜度o(1),不穩(wěn)定排序");" end="System.currentTimeMillis();" h2="" hashmap="" hhf="" hillsort="" i="1;" id="希爾排序" import="" int="" integer="" j="" long="" n="" param="" pre="" private="" public="" start="System.currentTimeMillis();" static="" swapcount="0;//交換次數(shù)" void="" x="1;x<=d;x++){//一共有d組"></hashmap.size();></integer,></integer,></integer,integer></integer,integer></code>
冒泡排序
<code class="language-java hljs "><code class="language-java hljs ">import java.util.HashMap;
/**
* 冒泡排序
* @author HHF
* 2014年3月19日
*/
public class BubbleSort {
private static int contrastCount = 0;//對比次數(shù)
private static int swapCount = 0;//交換次數(shù)
public static void main(String[] args) {
System.out.println("冒泡排序:\n 第一輪使最大值沉淀到最底下,采用從頭開始的兩兩比較的辦法,如果i大于i++則交換,下一次有從第一個開始循環(huán),比較次數(shù)減一,然后依次重復即可,"
+ "\n 如果一次比較為發(fā)生任何交換,則可提前終止,時間復雜度O(n^2),空間復雜度O(1),穩(wěn)定排序");
HashMap<integer,integer> hashMap = new HashMap<integer,integer>();
init(hashMap);//初始化
System.out.println("初始序列為:");
print(hashMap, 0);//打印
bubble(hashMap);//排序
}
/**
* 初始化函數(shù)
* @param hashMap
*/
private static void init(HashMap<integer, integer=""> hashMap) {
hashMap.put(0, null);//第一位置空
hashMap.put(1, 10);
hashMap.put(2, 5);
hashMap.put(3, 11);
hashMap.put(4, 12);
hashMap.put(5, 13);
hashMap.put(6, 4);
hashMap.put(7, 1);
hashMap.put(8, 5);
hashMap.put(9, 8);
hashMap.put(10, 6);
hashMap.put(11, 4);
hashMap.put(12, 8);
}
/**
* 進行冒泡排序
* @param hashMap 待排序的表
*/
private static void bubble(HashMap<integer, integer=""> hashMap){
System.out.println("開始冒泡排序:");
//排序開始時間
long start = System.currentTimeMillis();
boolean swap = false;//是否發(fā)生交換
int count = 1;//只為了計數(shù)
for(int i=1; i<hashmap.size(); int="" j="1;" swap="false;">hashMap.get(j+1)){//需要發(fā)生交換j 和 j+1
hashMap.put(0, hashMap.get(j));
hashMap.put(j, hashMap.get(j+1));
hashMap.put(j+1, hashMap.get(0));
swap = true;
contrastCount++;//發(fā)生一次對比
swapCount++;//發(fā)生一次交換
swapCount++;//發(fā)生一次交換
swapCount++;//發(fā)生一次交換
}
contrastCount++;//跳出if還有一次對比
}
print(hashMap, count++);
if(!swap)
break;
}
//排序結(jié)束時間
long end = System.currentTimeMillis();
System.out.println("結(jié)果為:");
print(hashMap, 0);//輸出排序結(jié)束的序列
hashMap.clear();//清空
System.out.print("一共發(fā)生了 "+contrastCount+" 次對比\t");
System.out.print("一共發(fā)生了 "+swapCount+" 次交換\t");
System.out.println("執(zhí)行時間為"+(end-start)+"毫秒");
}
/**
* 打印已排序好的元素
* @param hashMap 已排序的表
* @param j 第j趟排序
*/
private static void print(HashMap<integer, integer=""> hashMap, int j){
if(j != 0)
System.out.print("第 "+j+" 趟:\t");
for(int i=1; i<hashmap.size(); code=""></hashmap.size();></integer,></hashmap.size();></integer,></integer,></integer,integer></integer,integer></code></code>
快速排序
<code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs ">import java.util.HashMap;
public class QuickSort {
private static int contrastCount = 0;//對比次數(shù)
private static int swapCount = 0;//交換次數(shù)
public static void main(String[] args) {
System.out.println("快速排序:\n 任取一個數(shù)作為分界線,比它小的放到左邊,比它大的放在其右邊,然后分別對左右進行遞歸,時間復雜度O(nLgn),空間復雜度O(n),不穩(wěn)定排序");
HashMap<integer,integer> hashMap = new HashMap<integer,integer>();
init(hashMap);//初始化
System.out.println("初始序列為:");
print(hashMap, 0, 0);//打印
System.out.println("開始快速排序:");
//排序開始時間
long start = System.currentTimeMillis();
quick(hashMap, 1, hashMap.size()-1);//排序
//排序結(jié)束時間
long end = System.currentTimeMillis();
System.out.println("結(jié)果為:");
print(hashMap, 0, 0);//輸出排序結(jié)束的序列
hashMap.clear();//清空
System.out.print("一共發(fā)生了 "+contrastCount+" 次對比\t");
System.out.print("一共發(fā)生了 "+swapCount+" 次交換\t");
System.out.println("執(zhí)行時間為"+(end-start)+"毫秒");
System.out.println("(注:此輸出序列為代碼執(zhí)行過程的序列, 即先左邊遞歸 再 右邊遞歸, 而教科書上的遞歸序列往往是左右同時進行的結(jié)果,特此說明)");
}
/**
* 初始化函數(shù)
* @param hashMap
*/
private static void init(HashMap<integer, integer=""> hashMap) {
hashMap.put(0, null);//第一位置空
hashMap.put(1, 10);
hashMap.put(2, 5);
hashMap.put(3, 11);
hashMap.put(4, 12);
hashMap.put(5, 13);
hashMap.put(6, 4);
hashMap.put(7, 1);
hashMap.put(8, 5);
hashMap.put(9, 8);
hashMap.put(10, 6);
hashMap.put(11, 4);
hashMap.put(12, 8);
}
/**
* 進行快速排序
* @param hashMap 待排序的表
* @param low
* @param high
*/
static int count = 1;
private static void quick(HashMap<integer, integer=""> hashMap, int low, int high){
if(low<high){ hashmap="" high="" int="" integer="" k="quickOnePass(hashMap," low="" param="" private="" static=""> hashMap, int low, int high){
hashMap.put(0, hashMap.get(low));//選擇一個分界值 此時第low位元素內(nèi)的值已經(jīng)無所謂被覆蓋了
swapCount++;//發(fā)生一次交換
while(low<high){ high="">hashMap.get(low)){//開始從左往右走 直到有不對的數(shù)據(jù) 或者 到頭了
low++;
contrastCount++;//發(fā)生一次對比
}
if(low<high){ hashmap="" integer="" j="" k="" param="" private="" return="" static="" void=""> hashMap, int j, int k){
if(j != 0)
System.out.print("第 "+j+" 趟:(分界線為"+k+")\t");
for(int i=1; i<hashmap.size(); code=""></hashmap.size();></high){></high){></high){></integer,></integer,></integer,integer></integer,integer></code></code></code>
直接選擇排序
<code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs ">import java.util.HashMap;
public class SelectionSort {
private static int contrastCount = 0;//對比次數(shù)
private static int swapCount = 0;//交換次數(shù)
public static void main(String[] args) {
System.out.println("選擇排序:\n 每次選擇最小的,然后與對應的位置處元素交換,時間復雜度O(n^2),空間復雜度O(1),不穩(wěn)定排序");
HashMap<integer,integer> hashMap = new HashMap<integer,integer>();
init(hashMap);//初始化
System.out.println("初始序列為:");
print(hashMap, 0, 0);//打印
select(hashMap);//排序
}
/**
* 初始化函數(shù)
* @param hashMap
*/
private static void init(HashMap<integer, integer=""> hashMap) {
hashMap.put(0, null);//第一位置空
hashMap.put(1, 10);
hashMap.put(2, 5);
hashMap.put(3, 11);
hashMap.put(4, 12);
hashMap.put(5, 13);
hashMap.put(6, 4);
hashMap.put(7, 1);
hashMap.put(8, 5);
hashMap.put(9, 8);
hashMap.put(10, 6);
hashMap.put(11, 4);
hashMap.put(12, 8);
}
/**
* 進行選擇排序
* @param hashMap 待排序的表
*/
private static void select(HashMap<integer, integer=""> hashMap){
System.out.println("開始選擇排序:");
//排序開始時間
long start = System.currentTimeMillis();
int count = 1;//只為統(tǒng)計執(zhí)行次數(shù)
for(int i=hashMap.size()-1; i>1; i--){//需要循環(huán)查詢的次數(shù) 最后一個元素不用考慮
int k = i;//記錄本次查找序列最大值的下標 初始為該數(shù)應該要放的位置
for(int j=1; j<i; code="" i="1;" int="" j=""></i;></integer,></integer,></integer,integer></integer,integer></code></code></code></code>
堆排序
<code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs ">import java.util.HashMap;
public class HeapSort {
private static int contrastCount = 0;//對比次數(shù)
private static int swapCount = 0;//交換次數(shù)
private static int printCount = 1;//執(zhí)行打印次數(shù)
public static void main(String[] args) {
System.out.println("堆排序:\n 首先建立一個堆(方法是首先把序列排成二叉樹,然后從下往上,從右往左使得每一個小子樹中的父節(jié)點大于子節(jié)點,然后從上往下,從左往右記錄堆入序列),"
+ "\n 然后把堆的根節(jié)點和最底下 的孩子節(jié)點交換,整理堆,再重復交換,整理,時間復雜度O(nlgn),空間復雜度O(1),不穩(wěn)定排序");
HashMap<integer,integer> hashMap = new HashMap<integer,integer>();
init(hashMap);//初始化
System.out.println("初始序列為:");
print(hashMap, 0);//打印
heap(hashMap);//排序
}
/**
* 初始化函數(shù)
* @param hashMap
*/
private static void init(HashMap<integer, integer=""> hashMap) {
hashMap.put(0, null);//第一位置空
hashMap.put(1, 10);
hashMap.put(2, 5);
hashMap.put(3, 11);
hashMap.put(4, 12);
hashMap.put(5, 13);
hashMap.put(6, 4);
hashMap.put(7, 1);
hashMap.put(8, 5);
hashMap.put(9, 8);
hashMap.put(10, 6);
hashMap.put(11, 4);
hashMap.put(12, 8);
}
/**
* 進行堆排序
* @param hashMap 待排序的表
*/
private static void heap(HashMap<integer, integer=""> hashMap){
System.out.println("開始建堆:");
//排序開始時間87
long start = System.currentTimeMillis();
for(int i=(hashMap.size()-1)/2; i>=1; i--){//開始建堆
sift(hashMap, i, hashMap.size()-1);//把所有的節(jié)點調(diào)好位置即可以
}
System.out.println("建堆成功");
for(int j=hashMap.size()-1; j>=1; j--){//每次都把第一個元素與最后一個未排序的交換 然后再調(diào)整第一個節(jié)點即可
hashMap.put(0, hashMap.get(1));
hashMap.put(1, hashMap.get(j));
hashMap.put(j, hashMap.get(0));
sift(hashMap, 1, j-1);//剩下要排序的數(shù)位為j-1
swapCount++;//發(fā)生一次交換
swapCount++;//發(fā)生一次交換
swapCount++;//發(fā)生一次交換
}
//排序結(jié)束時間
long end = System.currentTimeMillis();
System.out.println("結(jié)果為:");
print(hashMap, 0);//輸出排序結(jié)束的序列
hashMap.clear();//清空
System.out.print("一共發(fā)生了 "+contrastCount+" 次對比\t");
System.out.print("一共發(fā)生了 "+swapCount+" 次交換\t");
System.out.println("執(zhí)行時間為"+(end-start)+"毫秒");
}
/**
* 把第i位的元素移動到合適位置 與其子孩子的最大值比較 如果有發(fā)生交換 則繼續(xù)往下比較
* @param hashMap
* @param i 待移動的數(shù)下標
* @param n 表示要查找的范圍 從1到n個
*/
private static void sift(HashMap<integer, integer=""> hashMap, int i, int n){
int j = 2*i;//j為i的左孩子
hashMap.put(0, hashMap.get(i));//當前被待排序的數(shù)
while(j<=n){//如果有左孩子的
if(hashMap.containsKey(j+1) && hashMap.get(j)<hashmap.get(j+1)){ else="" hashmap="" i="j;//轉(zhuǎn)移根節(jié)點下標" integer="" j="" param="" private="" static="" void=""> hashMap, int j){
if(j != 0)
System.out.print("第 "+j+" 趟:\t");
for(int i=1; i<hashmap.size(); code=""></hashmap.size();></hashmap.get(j+1)){></integer,></integer,></integer,></integer,integer></integer,integer></code></code></code></code></code>
歸并排序
<code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs ">import java.util.HashMap;
public class MergeSort {
private static int contrastCount = 0;//對比次數(shù)
private static int swapCount = 0;//交換次數(shù)
private static int printCount = 1;//只為統(tǒng)計執(zhí)行次數(shù)
public static void main(String[] args) {
System.out.println("歸并爾排序:\n 先將數(shù)據(jù)分為n組,然后沒兩組開始合并,相鄰兩個合并為一個新的有序隊列,重復合并直到整個隊列有序,時間復雜度O(nlgn),空間復雜度O(n),穩(wěn)定排序");
HashMap<integer,integer> hashMap = new HashMap<integer,integer>();//未排序
HashMap<integer,integer> hashMapNew = new HashMap<integer,integer>();//已排序
hashMapNew.put(0, null);//第一位置空
init(hashMap);//初始化
System.out.println("初始序列為:");
print(hashMap, 0);//打印
System.out.println("開始歸并爾排序:");
//排序開始時間
long start = System.currentTimeMillis();
merge(hashMap, hashMapNew, 1, hashMap.size()-1);//排序
//排序結(jié)束時間
long end = System.currentTimeMillis();
System.out.println("結(jié)果為:");
print(hashMapNew, 0);//輸出排序結(jié)束的序列
hashMap.clear();//清空
System.out.print("一共發(fā)生了 "+contrastCount+" 次對比\t");
System.out.print("一共發(fā)生了 "+swapCount+" 次交換\t");
System.out.println("執(zhí)行時間為"+(end-start)+"毫秒");
System.out.println("(注:此輸出序列為代碼執(zhí)行過程的序列, 即先左邊遞歸 再 右邊遞歸, 而教科書上的遞歸序列往往是左右同時進行的結(jié)果,特此說明)");
}
/**
* 初始化函數(shù)
* @param hashMap
*/
private static void init(HashMap<integer, integer=""> hashMap) {
hashMap.put(0, null);//第一位置空
hashMap.put(1, 10);
hashMap.put(2, 5);
hashMap.put(3, 11);
hashMap.put(4, 12);
hashMap.put(5, 13);
hashMap.put(6, 4);
hashMap.put(7, 1);
hashMap.put(8, 5);
hashMap.put(9, 8);
hashMap.put(10, 6);
hashMap.put(11, 4);
hashMap.put(12, 8);
}
/**
* 進行歸并爾排序
* @param hashMap 待排序的表
* @param hashMapNew 已排序的表
*/
private static void merge(HashMap<integer, integer=""> hashMap, HashMap<integer, integer=""> hashMapNew, int low, int high){
if(low == high){
hashMapNew.put(low, hashMap.get(low));
swapCount++;//發(fā)生一次交換
}else{
int meddle = (int)((low+high)/2);//將這一序列數(shù)均分的中間值
merge(hashMap, hashMapNew, low, meddle);//繼續(xù)對左邊的序列遞歸
merge(hashMap, hashMapNew, meddle+1, high);//對右邊的序列遞歸
mergeSort(hashMap, hashMapNew, low, meddle, high);//把相鄰的序列組合起來
for(int i=low; i<=high; i++){//將已經(jīng)排好序的hashMapNew【low,high】覆蓋hashMap【low,high】以便進入下一次的遞歸歸并
hashMap.put(i, hashMapNew.get(i));
swapCount++;//發(fā)生一次交換
}
}
}
/**
* 進行歸并爾排序 把【low,meddle】和【meddle+1,high】和并為一個有序的hashMapNew【low,high】
* @param hashMap 待排序的表
* @param hashMapNew 已排序的表
* @param low 低位
* @param meddle 中位
* @param high 高位
*/
private static void mergeSort(HashMap<integer, integer=""> hashMap, HashMap<integer, integer=""> hashMapNew, int low, int meddle, int high){
int k = low;
int j = meddle+1;
while(low<=meddle && j<=high){//兩個序列組合成一個序列 從小到達的順序
if(hashMap.get(low) < hashMap.get(j)){
hashMapNew.put(k++, hashMap.get(low++));//放入合適的位置
}else{
hashMapNew.put(k++, hashMap.get(j++));//放入合適的位置
}
contrastCount++;//發(fā)生一次對比
swapCount++;//發(fā)生一次交換
}
//如果有一方多出來了 則直接賦值
while(low<=meddle){
hashMapNew.put(k++, hashMap.get(low++));//放入合適的位置
swapCount++;//發(fā)生一次交換
}
while(j<=high){
hashMapNew.put(k++, hashMap.get(j++));//放入合適的位置
swapCount++;//發(fā)生一次交換
}
print(hashMapNew, printCount++);
}
/**
* 打印已排序好的元素
* @param hashMap 已排序的表
* @param j 第j趟排序
*/
private static void print(HashMap<integer, integer=""> hashMap, int j){
if(j != 0)
System.out.print("第 "+j+" 趟:\t");
for(int i=1; i<hashmap.size(); code=""></hashmap.size();></integer,></integer,></integer,></integer,></integer,></integer,></integer,integer></integer,integer></integer,integer></integer,integer></code></code></code></code></code></code>
最低位優(yōu)先基數(shù)排序
<code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs "><code class="language-java hljs ">/**
* 最低位優(yōu)先基數(shù)排序
* @author HHF
*
*/
public class LSDSort {
private static int contrastCount = 0;//對比次數(shù)
private static int swapCount = 0;//交換次數(shù)
private static int printCount = 1;//只為統(tǒng)計執(zhí)行次數(shù)
public static void main(String[] args) {
System.out.println("最低位優(yōu)先基數(shù)排序:\n 按個位、十位、百位排序,不需要比較,只需要對數(shù)求余然后保存到相應下標的二維數(shù)組內(nèi),然后依次讀取,每一進制重復依次 ,時間復雜度O(d(n+rd)),空間復雜度O(n+rd),穩(wěn)定排序");
int[] data = { 173, 22, 93, 43, 55, 14, 28, 65, 39, 81, 33, 100 };
System.out.println("初始序列為:");
print(data, 0);//打印
LSD(data, 3);
}
public static void LSD(int[] number, int d) {// d表示最大的數(shù)有多少位
int k = 0;//number的小標
int n = 1;//當比較十位的時候 n=10 比較百位的時候 n=100 用來吧高位降低方便求余數(shù)
int m = 1;//正在比較number中數(shù)據(jù)的倒數(shù)第幾位
int[][] temp = new int[10][number.length];// 數(shù)組的第一維表示可能的余數(shù)0-9 二維依次記錄該余數(shù)相同的數(shù)
int[] order = new int[10];// 數(shù)組orderp[i]用來表示該位的余數(shù)是i的數(shù)的個數(shù)
//排序開始時間
long start = System.currentTimeMillis();
while (m <= d) {//d=5則比較五次
for (int i = 0; i < number.length; i++) {//把number中的數(shù)按余數(shù)插入到temp中去
int lsd = ((number[i] / n) % 10);//求得該數(shù)的余數(shù)
temp[lsd][order[lsd]] = number[i];//保存到相應的地方
order[lsd]++;//該余數(shù)有幾個
swapCount++;//發(fā)生一次交換
}
for (int i = 0; i < 10; i++) {//將temp中的數(shù)據(jù)按順序提取出來
if (order[i] != 0)//如果該余數(shù)沒有數(shù)據(jù)則不需要考慮
for (int j = 0; j < order[i]; j++) {//有給余數(shù)的數(shù)一共有多少個
number[k] = temp[i][j];//一一賦值
k++;
swapCount++;//發(fā)生一次交換
}
order[i] = 0;//置零,以便下一次使用
}
n *= 10;//進制+1 往前走
k = 0;//從頭開始
m++;//進制+1
print(number, printCount++);
}
//排序結(jié)束時間
long end = System.currentTimeMillis();
System.out.println("結(jié)果為:");
print(number, 0);//輸出排序結(jié)束的序列
System.out.print("一共發(fā)生了 "+contrastCount+" 次對比\t");
System.out.print("一共發(fā)生了 "+swapCount+" 次交換\t");
System.out.println("執(zhí)行時間為"+(end-start)+"毫秒");
}
/**
* 打印已排序好的元素
* @param data 已排序的表
* @param j 第j趟排序
*/
private static void print(int[] data, int j){
if(j != 0)
System.out.print("第 "+j+" 趟:\t");
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
}
} </code></code></code></code></code></code></code>
本篇文章希望能幫助到您
相關(guān)文章
jvm雙親委派 vs 破壞雙親委派理解加載器的權(quán)責分配
這篇文章主要為大家介紹了jvm雙親委派 vs 破壞雙親委派對比來理解加載器的權(quán)責分配,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-10-10
Java并發(fā)工具類CountDownLatch CyclicBarrier使用詳解
這篇文章主要為大家介紹了Java并發(fā)工具類CountDownLatch CyclicBarrier使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-06-06
mybatis TypeHandler注入spring的依賴方式
這篇文章主要介紹了mybatis TypeHandler注入spring的依賴方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01
SpringBoot?整合?ElasticSearch操作各種高級查詢搜索
這篇文章主要介紹了SpringBoot?整合?ES?進行各種高級查詢搜索的實踐記錄,本文主要圍繞?SpringBoot?整合?ElasticSearch?進行各種高級查詢的介紹,需要的朋友可以參考下2022-06-06

