日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

常用排序讲解

發(fā)布時間:2023/12/20 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 常用排序讲解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

分類:

1)插入排序(直接插入排序、希爾排序)
2)交換排序(冒泡排序、快速排序)
3)選擇排序(直接選擇排序、堆排序)
4)歸并排序
5)分配排序(基數(shù)排序)
所需輔助空間最多:歸并排序
所需輔助空間最少:堆排序
平均速度最快:快速排序

不穩(wěn)定:快速排序,希爾排序,堆排序。

?

先來看看8種排序之間的關(guān)系:

??

?1.直接插入排序

(1)基本思想:在要排序的一組數(shù)中,假設(shè)前面(n-1)[n>=2] 個數(shù)已經(jīng)是排

好順序的,現(xiàn)在要把第n個數(shù)插到前面的有序數(shù)中,使得這n個數(shù)

也是排好順序的。如此反復(fù)循環(huán),直到全部排好順序。

(2)實例

(3)用java實現(xiàn)

?

[java]?view plain?copy?print?
  • package?com.njue;??
  • ??
  • publicclass?insertSort?{??
  • ??
  • public?insertSort(){??
  • ????inta[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};??
  • ????int?temp=0;??
  • ????for(int?i=1;i<a.length;i++){??
  • ???????int?j=i-1;??
  • ???????temp=a[i];??
  • ???????for(;j>=0&&temp<a[j];j--){??
  • ???????????a[j+1]=a[j];??//將大于temp的值整體后移一個單位??
  • ???????}??
  • ???????a[j+1]=temp;??
  • ????}??
  • ??
  • ????for(int?i=0;i<a.length;i++){??
  • ???????System.out.println(a[i]);??
  • ????}??
  • }??


  • 2.?? 希爾排序(最小增量排序)

    (1)基本思想:算法先將要排序的一組數(shù)按某個增量d(n/2,n為要排序數(shù)的個數(shù))分成若干組,每組中記錄的下標相差d.對每組中全部元素進行直接插入排序,然后再用一個較小的增量(d/2)對它進行分組,在每組中再進行直接插入排序。當增量減到1時,進行直接插入排序后,排序完成。

    (2)實例:

    (3)用java實現(xiàn)

    [java]?view plain?copy?print?
  • publicclass?shellSort?{??
  • ??
  • publicshellSort(){??
  • ??
  • ????int?a[]={1,54,6,3,78,34,12,45,56,100};??
  • ????double?d1=a.length;??
  • ????int?temp=0;??
  • ??
  • ????while(true){??
  • ???????d1=?Math.ceil(d1/2);??
  • ???????int?d=(int)?d1;??
  • ???????for(int?x=0;x<d;x++){??
  • ??
  • ???????????for(int?i=x+d;i<a.length;i+=d){??
  • ??????????????int?j=i-d;??
  • ??????????????temp=a[i];??
  • ??????????????for(;j>=0&&temp<a[j];j-=d){??
  • ???????????????????a[j+d]=a[j];??
  • ??????????????}??
  • ??????????????a[j+d]=temp;??
  • ???????????}??
  • ???????}??
  • ??
  • ???????if(d==1){??
  • ???????????break;??
  • ???????}??
  • ??
  • ????for(int?i=0;i<a.length;i++){??
  • ???????System.out.println(a[i]);??
  • ????}??
  • }??
  • ?

    3.簡單選擇排序

    (1)基本思想:在要排序的一組數(shù)中,選出最小的一個數(shù)與第一個位置的數(shù)交換;

    然后在剩下的數(shù)當中再找最小的與第二個位置的數(shù)交換,如此循環(huán)到倒數(shù)第二個數(shù)和最后一個數(shù)比較為止。

    (2)實例:

    (3)用java實現(xiàn)

    [java]?view plain?copy?print?
  • publicclass?selectSort?{??
  • ??
  • ????public?selectSort(){??
  • ???????int?a[]={1,54,6,3,78,34,12,45};??
  • ???????int?position=0;??
  • ???????for(int?i=0;i<a.length;i++){???????
  • ???????????int?j=i+1;??
  • ???????????position=i;??
  • ???????????int?temp=a[i];??
  • ???????????for(;j<a.length;j++){??
  • ??????????????if(a[j]<temp){??
  • ?????????????????temp=a[j];??
  • ?????????????????position=j;??
  • ??????????????}??
  • ???????????}??
  • ???????????a[position]=a[i];??
  • ???????????a[i]=temp;??
  • ???????}??
  • ??
  • ???????for(int?i=0;i<a.length;i++)??
  • ???????????System.out.println(a[i]);??
  • ????}??
  • }??
  • ?

    4,??????堆排序

    (1)基本思想:堆排序是一種樹形選擇排序,是對直接選擇排序的有效改進。

    堆的定義如下:具有n個元素的序列(h1,h2,...,hn),當且僅當滿足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)時稱之為堆。在這里只討論滿足前者條件的堆。由堆的定義可以看出,堆頂元素(即第一個元素)必為最大項(大頂堆)。完全二叉樹可以很直觀地表示堆的結(jié)構(gòu)。堆頂為根,其它為左子樹、右子樹。初始時把要排序的數(shù)的序列看作是一棵順序存儲的二叉樹,調(diào)整它們的存儲序,使之成為一個堆,這時堆的根節(jié)點的數(shù)最大。然后將根節(jié)點與堆的最后一個節(jié)點交換。然后對前面(n-1)個數(shù)重新調(diào)整使之成為堆。依此類推,直到只有兩個節(jié)點的堆,并對它們作交換,最后得到有n個節(jié)點的有序序列。從算法描述來看,堆排序需要兩個過程,一是建立堆,二是堆頂與堆的最后一個元素交換位置。所以堆排序有兩個函數(shù)組成。一是建堆的滲透函數(shù),二是反復(fù)調(diào)用滲透函數(shù)實現(xiàn)排序的函數(shù)。

    (2)實例:

    初始序列:46,79,56,38,40,84

    建堆:

    交換,從堆中踢出最大數(shù)

    剩余結(jié)點再建堆,再交換踢出最大數(shù)

    依次類推:最后堆中剩余的最后兩個結(jié)點交換,踢出一個,排序完成。

    (3)用java實現(xiàn)

    [java]?view plain?copy?print?
  • import?java.util.Arrays;??
  • ??
  • publicclass?HeapSort?{??
  • ????inta[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};??
  • ????public??HeapSort(){??
  • ???????heapSort(a);??
  • ????}??
  • ??
  • ????public??void?heapSort(int[]?a){??
  • ????????System.out.println("開始排序");??
  • ????????int?arrayLength=a.length;??
  • ????????//循環(huán)建堆??
  • ????????for(int?i=0;i<arrayLength-1;i++){??
  • ????????????//建堆??
  • ????????????buildMaxHeap(a,arrayLength-1-i);??
  • ????????????//交換堆頂和最后一個元素??
  • ????????????swap(a,0,arrayLength-1-i);??
  • ????????????System.out.println(Arrays.toString(a));??
  • ????????}??
  • ????}??
  • ??
  • ???
  • ??
  • ????private??void?swap(int[]?data,?int?i,?int?j)?{??
  • ????????//?TODO?Auto-generated?method?stub??
  • ????????int?tmp=data[i];??
  • ????????data[i]=data[j];??
  • ????????data[j]=tmp;??
  • ????}??
  • ??
  • ????//對data數(shù)組從0到lastIndex建大頂堆??
  • ????privatevoid?buildMaxHeap(int[]?data,?int?lastIndex)?{??
  • ????????//?TODO?Auto-generated?method?stub??
  • ????????//從lastIndex處節(jié)點(最后一個節(jié)點)的父節(jié)點開始??
  • ??
  • ????????for(int?i=(lastIndex-1)/2;i>=0;i--){??
  • ????????????//k保存正在判斷的節(jié)點??
  • ????????????int?k=i;??
  • ????????????//如果當前k節(jié)點的子節(jié)點存在??
  • ????????????while(k*2+1<=lastIndex){??
  • ????????????????//k節(jié)點的左子節(jié)點的索引??
  • ????????????????int?biggerIndex=2*k+1;??
  • ????????????????//如果biggerIndex小于lastIndex,即biggerIndex+1代表的k節(jié)點的右子節(jié)點存在??
  • ????????????????if(biggerIndex<lastIndex){??
  • ????????????????????//若果右子節(jié)點的值較大??
  • ????????????????????if(data[biggerIndex]<data[biggerIndex+1]){??
  • ????????????????????????//biggerIndex總是記錄較大子節(jié)點的索引??
  • ????????????????????????biggerIndex++;??
  • ????????????????????}??
  • ????????????????}??
  • ??
  • ????????????????//如果k節(jié)點的值小于其較大的子節(jié)點的值??
  • ???????????????if(data[k]<data[biggerIndex]){??
  • ????????????????????//交換他們??
  • ????????????????????swap(data,k,biggerIndex);??
  • ????????????????????//將biggerIndex賦予k,開始while循環(huán)的下一次循環(huán),重新保證k節(jié)點的值大于其左右子節(jié)點的值??
  • ????????????????????k=biggerIndex;??
  • ????????????????}else{??
  • ????????????????????break;??
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ????}??
  • }??
  • ?

    5.冒泡排序

    (1)基本思想:在要排序的一組數(shù)中,對當前還未排好序的范圍內(nèi)的全部數(shù),自上而下對相鄰的兩個數(shù)依次進行比較和調(diào)整,讓較大的數(shù)往下沉,較小的往上冒。即:每當兩相鄰的數(shù)比較后發(fā)現(xiàn)它們的排序與排序要求相反時,就將它們互換。

    (2)實例:

    (3)用java實現(xiàn)

    [java]?view plain?copy?print?
  • publicclass?bubbleSort?{??
  • ??
  • publicbubbleSort(){??
  • ?????inta[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};??
  • ????int?temp=0;??
  • ????for(int?i=0;i<a.length-1;i++){??
  • ???????for(int?j=0;j<a.length-1-i;j++){??
  • ?????????if(a[j]>a[j+1]){??
  • ???????????temp=a[j];??
  • ???????????a[j]=a[j+1];??
  • ???????????a[j+1]=temp;??
  • ?????????}??
  • ???????}??
  • ????}??
  • ??
  • ????for(int?i=0;i<a.length;i++){??
  • ???????System.out.println(a[i]);????
  • ???}??
  • }??


  • 6.快速排序

    (1)基本思想:選擇一個基準元素,通常選擇第一個元素或者最后一個元素,通過一趟掃描,將待排序列分成兩部分,一部分比基準元素小,一部分大于等于基準元素,此時基準元素在其排好序后的正確位置,然后再用同樣的方法遞歸地排序劃分的兩部分。

    (2)實例:

    (3)用java實現(xiàn)

    ?

    [java]?view plain?copy?print?
  • publicclass?quickSort?{??
  • ??
  • ??inta[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};??
  • publicquickSort(){??
  • ????quick(a);??
  • ????for(int?i=0;i<a.length;i++){??
  • ???????System.out.println(a[i]);??
  • ????}??
  • }??
  • publicint?getMiddle(int[]?list,?int?low,?int?high)?{????
  • ????????????int?tmp?=list[low];????//數(shù)組的第一個作為中軸????
  • ????????????while?(low?<?high){????
  • ????????????????while?(low?<?high&&?list[high]?>=?tmp)?{????
  • ???????????????????high--;????
  • ????????????????}????
  • ??
  • ????????????????list[low]?=list[high];???//比中軸小的記錄移到低端????
  • ????????????????while?(low?<?high&&?list[low]?<=?tmp)?{????
  • ????????????????????low++;????
  • ????????????????}????
  • ??
  • ????????????????list[high]?=list[low];???//比中軸大的記錄移到高端????
  • ????????????}????
  • ???????????list[low]?=?tmp;??????????????//中軸記錄到尾????
  • ????????????return?low;???????????????????//返回中軸的位置????
  • }???
  • ??
  • publicvoid?_quickSort(int[]?list,?int?low,?int?high)?{????
  • ????????????if?(low?<?high){????
  • ???????????????int?middle?=getMiddle(list,?low,?high);??//將list數(shù)組進行一分為二????
  • ???????????????_quickSort(list,?low,?middle?-?1);???????//對低字表進行遞歸排序????
  • ???????????????_quickSort(list,middle?+?1,?high);???????//對高字表進行遞歸排序????
  • ????????????}????
  • }??
  • ??
  • publicvoid?quick(int[]?a2)?{????
  • ????????????if?(a2.length?>?0)?{????//查看數(shù)組是否為空????
  • ????????????????_quickSort(a2,0,?a2.length?-?1);????
  • ????????????}????
  • }??
  • }??
  • ?

    7、歸并排序

    ?

    (1)基本排序:歸并(Merge)排序法是將兩個(或兩個以上)有序表合并成一個新的有序表,即把待排序序列分為若干個子序列,每個子序列是有序的。然后再把有序子序列合并為整體有序序列。

    (2)實例:

    (3)用java實現(xiàn)

    [java]?view plain?copy?print?
  • import?java.util.Arrays;??
  • ??
  • publicclass?mergingSort?{??
  • ??
  • inta[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};??
  • ??
  • publicmergingSort(){??
  • ????sort(a,0,a.length-1);??
  • ????for(int?i=0;i<a.length;i++)??
  • ???????System.out.println(a[i]);??
  • }??
  • ??
  • publicvoid?sort(int[]?data,?int?left,?int?right)?{??
  • ????//?TODO?Auto-generatedmethod?stub??
  • ????if(left<right){??
  • ????????//找出中間索引??
  • ????????int?center=(left+right)/2;??
  • ????????//對左邊數(shù)組進行遞歸??
  • ????????sort(data,left,center);??
  • ????????//對右邊數(shù)組進行遞歸??
  • ????????sort(data,center+1,right);??
  • ????????//合并??
  • ????????merge(data,left,center,right);?????????
  • ????}??
  • ??
  • }??
  • ??
  • publicvoid?merge(int[]?data,?int?left,?int?center,?int?right)?{??
  • ????//?TODO?Auto-generatedmethod?stub??
  • ????int?[]?tmpArr=newint[data.length];??
  • ????int?mid=center+1;??
  • ????//third記錄中間數(shù)組的索引??
  • ????int?third=left;??
  • ????int?tmp=left;??
  • ????while(left<=center&&mid<=right){??
  • ????????//從兩個數(shù)組中取出最小的放入中間數(shù)組??
  • ????????if(data[left]<=data[mid]){??
  • ????????????tmpArr[third++]=data[left++];??
  • ????????}else{??
  • ????????????tmpArr[third++]=data[mid++];??
  • ????????}??
  • ??
  • ????}??
  • ??
  • ????//剩余部分依次放入中間數(shù)組??
  • ????while(mid<=right){??
  • ????????tmpArr[third++]=data[mid++];??
  • ????}??
  • ??
  • ????while(left<=center){??
  • ????????tmpArr[third++]=data[left++];??
  • ????}??
  • ??
  • ????//將中間數(shù)組中的內(nèi)容復(fù)制回原數(shù)組??
  • ????while(tmp<=right){??
  • ????????data[tmp]=tmpArr[tmp++];??
  • ????}??
  • ????System.out.println(Arrays.toString(data));??
  • }??
  • }??
  • ?

    8、基數(shù)排序

    ?

    (1)基本思想:將所有待比較數(shù)值(正整數(shù))統(tǒng)一為同樣的數(shù)位長度,數(shù)位較短的數(shù)前面補零。然后,從最低位開始,依次進行一次排序。這樣從最低位排序一直到最高位排序完成以后,數(shù)列就變成一個有序序列。

    (2)實例:

    (3)用java實現(xiàn)

    [java]?view plain?copy?print?
  • import?java.util.ArrayList;??
  • import?java.util.List;??
  • ??
  • public?class?radixSort?{??
  • ????inta[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,101,56,17,18,23,34,15,35,25,53,51};??
  • ????public?radixSort(){??
  • ???????sort(a);??
  • ???????for(inti=0;i<a.length;i++){??
  • ??????????????System.out.println(a[i]);??
  • ???????}??
  • ????}?????????
  • ????public??void?sort(int[]?array){????
  • ???????//首先確定排序的趟數(shù);????
  • ???????int?max=array[0];????
  • ???????for(inti=1;i<array.length;i++){????
  • ????????????if(array[i]>max){????
  • ??????????????max=array[i];????
  • ????????????}????
  • ???????}????
  • ???????int?time=0;????
  • ???????//判斷位數(shù);????
  • ???????while(max>0){????
  • ??????????max/=10;????
  • ???????????time++;????
  • ???????}????
  • ??
  • ????????//建立10個隊列;????
  • ???????List<ArrayList>?queue=newArrayList<ArrayList>();????
  • ???????for(int?i=0;i<10;i++){????
  • ??????????????ArrayList<Integer>queue1=new?ArrayList<Integer>();??
  • ???????????queue.add(queue1);????
  • ???????}????
  • ??
  • ???????//進行time次分配和收集;????
  • ???????for(int?i=0;i<time;i++){????
  • ???????????//分配數(shù)組元素;????
  • ??????????for(intj=0;j<array.length;j++){????
  • ???????????????//得到數(shù)字的第time+1位數(shù);??
  • ?????????????????int?x=array[j]%(int)Math.pow(10,i+1)/(int)Math.pow(10,?i);??
  • ?????????????????ArrayList<Integer>queue2=queue.get(x);??
  • ?????????????????queue2.add(array[j]);??
  • ?????????????????queue.set(x,?queue2);??
  • ??????????}???
  • ??????????int?count=0;//元素計數(shù)器;????
  • ??????????//收集隊列元素;????
  • ??????????for(int?k=0;k<10;k++){??
  • ???????????????while(queue.get(k).size()>0){??
  • ???????????????????ArrayList<Integer>queue3=queue.get(k);??
  • ???????????????????array[count]=queue3.get(0);????
  • ???????????????????queue3.remove(0);??
  • ???????????????????count++;??
  • ???????????????}???
  • ??????????}????
  • ???????}???????????????
  • ????}??
  • }??
  • 轉(zhuǎn)載于:https://www.cnblogs.com/qiumingcheng/p/5220616.html

    總結(jié)

    以上是生活随笔為你收集整理的常用排序讲解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。