主頁 > 後端開發 > 「干貨總結」程式員必知必會的十大排序演算法

「干貨總結」程式員必知必會的十大排序演算法

2020-12-03 11:40:14 後端開發

身為程式員,十大排序是是所有合格程式員所必備和掌握的,并且熱門的演算法比如快排、歸并排序還可能問的比較細致,對演算法性能和復雜度的掌握有要求,bigsai作為一個負責任的Java和資料結構與演算法方向的小博主,在這方面肯定不能讓讀者們有所漏洞,跟著本篇走,帶你捋一捋常見的十大排序演算法,輕輕松松掌握!

首先對于排序來說大多數人對排序的概念停留在冒泡排序或者JDK中的Arrays.sort(),手寫各種排序對很多人來說都是一種奢望,更別說十大排序演算法了,不過還好你遇到了本篇文章!

對于排序的分類,主要不同的維度比如復雜度來分、內外部、比較非比較等維度來分類,我們正常講的十大排序演算法是內部排序,我們更多將他們分為兩大類:基于比較和非比較這個維度去分排序種類,

  • 非比較類的有桶排序、基數排序、計數排序,也有很多人將排序歸納為8大排序,那就是因為基數排序、計數排序是建立在桶排序之上或者是一種特殊的桶排序,但是基數排序和計數排序有它特有的特征,所以在這里就將他們歸納為10種經典排序演算法,而比較類排序也可分為
  • 比較類排序也有更細致的分法,有基于交換的、基于插入的、基于選擇的、基于歸并的,更細致的可以看下面的腦圖,

image-20201120124138560

交換類

冒泡排序

冒泡排序,又稱起泡排序,它是一種基于交換的排序典型,也是快排思想的基礎,冒泡排序是一種穩定排序演算法,時間復雜度為O(n^2).基本思想是:回圈遍歷多次每次從前往后把大元素往后調,每次確定一個最大(最小)元素,多次后達到排序序列,(或者從后向前把小元素往前調),

具體思想為(把大元素往后調):

  • 從第一個元素開始往后遍歷,每到一個位置判斷是否比后面的元素大,如果比后面元素大,那么就交換兩者大小,然后繼續向后,這樣的話進行一輪之后就可以保證最大的那個數被交換交換到最末的位置可以確定
  • 第二次同樣從開始起向后判斷著前進,如果當前位置比后面一個位置更大的那么就和他后面的那個數交換,但是有點注意的是,這次并不需要判斷到最后,只需要判斷到倒數第二個位置就行(因為第一次我們已經確定最大的在倒數第一,這次的目的是確定倒數第二)
  • 同理,后面的遍歷長度每次減一,直到第一個元素使得整個元素有序,

例如2 5 3 1 4排序程序如下:

image-20201120155114930

實作代碼為:

public void  maopaosort(int[] a) {
  // TODO Auto-generated method stub
  for(int i=a.length-1;i>=0;i--)
  {
    for(int j=0;j<i;j++)
    {
      if(a[j]>a[j+1])
      {
        int team=a[j];
        a[j]=a[j+1];
        a[j+1]=team;
      }
    }
  }
}

 

 

快速排序

快速排序是對冒泡排序的一種改進,采用遞回分治的方法進行求解,而快排相比冒泡是一種不穩定排序,時間復雜度最壞是O(n^2),平均時間復雜度為O(nlogn),最好情況的時間復雜度為O(nlogn),

對于快排來說,基本思想是這樣的

  • 快排需要將序列變成兩個部分,就是序列左邊全部小于一個數序列右面全部大于一個數,然后利用遞回的思想再將左序列當成一個完整的序列再進行排序,同樣把序列的右側也當成一個完整的序列進行排序,
  • 其中這個數在這個序列中是可以隨機取的,可以取最左邊,可以取最右邊,當然也可以取亂數,但是通常不優化情況我們取最左邊的那個數,

image-20201120133851275

實作代碼為:

public void quicksort(int [] a,int left,int right)
{
  int low=left;
  int high=right;
  //下面兩句的順序一定不能混,否則會產生陣列越界!!!very important!!!
  if(low>high)//作為判斷是否截止條件
    return;
  int k=a[low];//額外空間k,取最左側的一個作為衡量,最后要求左側都比它小,右側都比它大,
  while(low<high)//這一輪要求把左側小于a[low],右側大于a[low],
  {
    while(low<high&&a[high]>=k)//右側找到第一個小于k的停止
    {
      high--;
    }
    //這樣就找到第一個比它小的了
    a[low]=a[high];//放到low位置
    while(low<high&&a[low]<=k)//在low往右找到第一個大于k的,放到右側a[high]位置
    {
      low++;
    }
    a[high]=a[low];         
  }
  a[low]=k;//賦值然后左右遞回分治求之
  quicksort(a, left, low-1);
  quicksort(a, low+1, right);       
}

 



插入類排序

直接插入排序

直接插入排序在所有排序演算法中的是最簡單排序方式之一,和我們上學時候 從前往后、按高矮順序排序,那么一堆高低無序的人群中,從第一個開始,如果前面有比自己高的,就直接插入到合適的位置,一直到隊伍的最后一個完成插入整個佇列才能滿足有序,

直接插入排序遍歷比較時間復雜度是每次O(n),交換的時間復雜度每次也是O(n),那么n次總共的時間復雜度就是O(n^2),有人會問折半(二分)插入能否優化成O(nlogn),答案是不能的,因為二分只能減少查找復雜度每次為O(logn),而插入的時間復雜度每次為O(n)級別,這樣總的時間復雜度級別還是O(n^2).

插入排序的具體步驟:

  • 選取當前位置(當前位置前面已經有序) 目標就是將當前位置資料插入到前面合適位置,
  • 向前列舉或者二分查找,找到待插入的位置,
  • 移動陣列,賦值交換,達到插入效果,

image-20201120160709469

實作代碼為:

public void insertsort (int a[])
{
  int team=0;
  for(int i=1;i<a.length;i++)
  {
    System.out.println(Arrays.toString(a));
    team=a[i];
    for(int j=i-1;j>=0;j--)
    {

      if(a[j]>team)
      {
        a[j+1]=a[j];
        a[j]=team;  
      } 
      else {
        break;
      }
    }
  } 
}

 



希爾排序

直接插入排序因為是O(n^2),在資料量很大或者資料移動位次太多會導致效率太低,很多排序都會想辦法拆分序列,然后組合,希爾排序就是以一種特殊的方式進行預處理,考慮到了資料量和有序性兩個方面緯度來設計演算法,使得序列前后之間小的盡量在前面,大的盡量在后面,進行若干次的分組別計算,最后一組即是一趟完整的直接插入排序,

對于一個長串,希爾首先將序列分割(非線性分割)而是按照某個數模(取余這個類似報數1、2、3、4,1、2、3、4)這樣形式上在一組的分割先各組分別進行直接插入排序,這樣很小的數在后面可以通過較少的次數移動到相對靠前的位置,然后慢慢合并變長,再稍稍移動,

因為每次這樣插入都會使得序列變得更加有序,稍微有序序列執行直接插入排序成本并不高,所以這樣能夠在合并到最終的時候基本小的在前,大的在后,代價越來越小,這樣希爾排序相比插入排序還是能節省不少時間的,

image-20201120164448973

實作代碼為:

public void shellsort (int a[])
{
  int d=a.length;
  int team=0;//臨時變數
  for(;d>=1;d/=2)//共分成d組
    for(int i=d;i<a.length;i++)//到那個元素就看這個元素在的那個組即可
    {
      team=a[i];
      for(int j=i-d;j>=0;j-=d)
      {             
        if(a[j]>team)
        {
          a[j+d]=a[j];
          a[j]=team;    
        }
        else {
          break;
        }
      }
    }   
}

 

 

選擇類排序

簡單選擇排序

簡單選擇排序(Selection sort)是一種簡單直觀的排序演算法,它的作業原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再從剩余未排序元素中繼續尋找最小(大)元素,然后放到已排序序列的末尾,以此類推,直到所有元素均排序完畢,

image-20201120201910761

實作代碼為:

public void selectSort(int[] arr) {
  for (int i = 0; i < arr.length - 1; i++) {
    int min = i; // 最小位置
    for (int j = i + 1; j < arr.length; j++) {
      if (arr[j] < arr[min]) {
        min = j; // 更換最小位置
      }
    }
    if (min != i) {
      swap(arr, i, min); // 與第i個位置進行交換
    }
  }
}
private void swap(int[] arr, int i, int j) {
  int temp = arr[i];
  arr[i] = arr[j];
  arr[j] = temp;
}

 



堆排序

對于堆排序,首先是建立在堆的基礎上,堆是一棵完全二叉樹,還要先認識下大根堆和小根堆,完全二叉樹中所有節點均大于(或小于)它的孩子節點,所以這里就分為兩種情況

  • 如果所有節點大于孩子節點值,那么這個堆叫做大根堆,堆的最大值在根節點,
  • 如果所有節點小于孩子節點值,那么這個堆叫做小根堆,堆的最小值在根節點,

在這里插入圖片描述

堆排序首先就是建堆,然后再是調整,對于二叉樹(陣串列示),我們從下往上進行調整,從第一個非葉子節點開始向前調整,對于調整的規則如下:

建堆是一個O(n)的時間復雜度程序,建堆完成后就需要進行洗掉頭排序,給定陣列建堆(creatHeap)

①從第一個非葉子節點開始判斷交換下移(shiftDown),使得當前節點和子孩子能夠保持堆的性質

②但是普通節點替換可能沒問題,對如果交換打破子孩子堆結構性質,那么就要重新下移(shiftDown)被交換的節點一直到停止,

在這里插入圖片描述

堆構造完成,取第一個堆頂元素為最小(最大),剩下左右孩子依然滿足堆的性值,但是缺個堆頂元素,如果給孩子調上來,可能會調動太多并且可能破壞堆結構,

①所以索性把最后一個元素放到第一位,這樣只需要判斷交換下移(shiftDown),不過需要注意此時整個堆的大小已經發生了變化,我們在邏輯上不會使用被拋棄的位置,所以在設計函式的時候需要附帶一個堆大小的引數,

②重復以上操作,一直堆中所有元素都被取得停止,

在這里插入圖片描述

而堆演算法復雜度的分析上,之前建堆時間復雜度是O(n),而每次洗掉堆頂然后需要向下交換,每個個數最壞為logn個,這樣復雜度就為O(nlogn).總的時間復雜度為O(n)+O(nlogn)=O(nlogn).

實作代碼為:

static void swap(int arr[],int m,int n)
{
  int team=arr[m];
  arr[m]=arr[n];
  arr[n]=team;
}
//下移交換 把當前節點有效變換成一個堆(小根)
static void shiftDown(int arr[],int index,int len)//0 號位置不用
{
  int leftchild=index*2+1;//左孩子
  int rightchild=index*2+2;//右孩子
  if(leftchild>=len)
    return;
  else if(rightchild<len&&arr[rightchild]<arr[index]&&arr[rightchild]<arr[leftchild])//右孩子在范圍內并且應該交換
  {
    swap(arr, index, rightchild);//交換節點值
    shiftDown(arr, rightchild, len);//可能會對孩子節點的堆有影響,向下重構
  }
  else if(arr[leftchild]<arr[index])//交換左孩子
  {
    swap(arr, index, leftchild);
    shiftDown(arr, leftchild, len);
  }
}
//將陣列創建成堆
static void creatHeap(int arr[])
{
  for(int i=arr.length/2;i>=0;i--)
  {
    shiftDown(arr, i,arr.length);
  }
}
static void heapSort(int arr[])
{
  System.out.println("原始陣列為         :"+Arrays.toString(arr));
  int val[]=new int[arr.length]; //臨時儲存結果
  //step1建堆
  creatHeap(arr);
  System.out.println("建堆后的序列為  :"+Arrays.toString(arr));
  //step2 進行n次取值建堆,每次取堆頂元素放到val陣列中,最終結果即為一個遞增排序的序列
  for(int i=0;i<arr.length;i++)
  {
    val[i]=arr[0];//將堆頂放入結果中
    arr[0]=arr[arr.length-1-i];//洗掉堆頂元素,將末尾元素放到堆頂
    shiftDown(arr, 0, arr.length-i);//將這個堆調整為合法的小根堆,注意(邏輯上的)長度有變化
  }
  //數值克隆復制
  for(int i=0;i<arr.length;i++)
  {
    arr[i]=val[i];
  }
  System.out.println("堆排序后的序列為:"+Arrays.toString(arr));

}

 

 

歸并類排序

在歸并類排序一般只講歸并排序,但是歸并排序也分二路歸并、多路歸并,這里就講較多的二路歸并排序,且用遞回方式實作,

歸并排序

歸并和快排都是基于分治演算法的,分治演算法其實應用挺多的,很多分治會用到遞回,但事實上分治和遞回是兩把事,分治就是分而治之,可以采用遞回實作,也可以自己遍歷實作非遞回方式,而歸并排序就是先將問題分解成代價較小的子問題,子問題再采取代價較小的合并方式完成一個排序,

至于歸并的思想是這樣的:

  • 第一次:整串先進行劃分成一個一個單獨,第一次是將序列中(1 2 3 4 5 6---)兩兩歸并成有序,歸并完(xx xx xx xx----)這樣區域有序的序列,
  • 第二次就是兩兩歸并成若干四個(1 2 3 4 5 6 7 8 ----)每個小區域是有序的
  • 就這樣一直到最后這個串串只剩一個,然而這個耗費的總次數logn,每次操作的時間復雜的又是O(n),所以總共的時間復雜度為O(nlogn).

image-20201120173153449

合并為一個O(n)的程序:

image-20201120174526108

實作代碼為:

private static void mergesort(int[] array, int left, int right) {
  int mid=(left+right)/2;
  if(left<right)
  {
    mergesort(array, left, mid);
    mergesort(array, mid+1, right);
    merge(array, left,mid, right);
  }
}

private static void merge(int[] array, int l, int mid, int r) {
  int lindex=l;int rindex=mid+1;
  int team[]=new int[r-l+1];
  int teamindex=0;
  while (lindex<=mid&&rindex<=r) {//先左右比較合并
    if(array[lindex]<=array[rindex])
    {
      team[teamindex++]=array[lindex++];
    }
    else {              
      team[teamindex++]=array[rindex++];
    }
  }
  while(lindex<=mid)//當一個越界后剩余按序列添加即可
  {
    team[teamindex++]=array[lindex++];

  }
  while(rindex<=r)
  {
    team[teamindex++]=array[rindex++];
  } 
  for(int i=0;i<teamindex;i++)
  {
    array[l+i]=team[i];
  }

}

 



桶類排序

桶排序

桶排序是一種用空間換取時間的排序,桶排序重要的是它的思想,而不是具體實作,時間復雜度最好可能是線性O(n),桶排序不是基于比較的排序而是一種分配式的,桶排序從字面的意思上看:

  • 桶:若干個桶,說明此類排序將資料放入若干個桶中,
  • 桶:每個桶有容量,桶是有一定容積的容器,所以每個桶中可能有多個元素,
  • 桶:從整體來看,整個排序更希望桶能夠更勻稱,即既不溢位(太多)又不太少,

桶排序的思想為:將待排序的序列分到若干個桶中,每個桶內的元素再進行個別排序, 當然桶排序選擇的方案跟具體的資料有關系,桶排序是一個比較廣泛的概念,并且計數排序是一種特殊的桶排序,基數排序也是建立在桶排序的基礎上,在資料分布均勻且每個桶元素趨近一個時間復雜度能達到O(n),但是如果資料范圍較大且相對集中就不太適合使用桶排序,

image-20201120180500488

實作一個簡單桶排序:

import java.util.ArrayList;
import java.util.List;
//微信公眾號:bigsai
public class bucketSort {
    public static void main(String[] args) {
        int a[]= {1,8,7,44,42,46,38,34,33,17,15,16,27,28,24};
        List[] buckets=new ArrayList[5];
        for(int i=0;i<buckets.length;i++)//初始化
        {
            buckets[i]=new ArrayList<Integer>();
        }
        for(int i=0;i<a.length;i++)//將待排序序列放入對應桶中
        {
            int index=a[i]/10;//對應的桶號
            buckets[index].add(a[i]);
        }
        for(int i=0;i<buckets.length;i++)//每個桶內進行排序(使用系統自帶快排)
        {
            buckets[i].sort(null);
            for(int j=0;j<buckets[i].size();j++)//順便列印輸出
            {
                System.out.print(buckets[i].get(j)+" ");
            }
        }   
    }
}

 



計數排序

計數排序是一種特殊的桶排序,每個桶的大小為1,每個桶不在用List表示,而通常用一個值用來計數,

設計具體演算法的時候,先找到最小值min,再找最大值max,然后創建這個區間大小的陣列,從min的位置開始計數,這樣就可以最大程度的壓縮空間,提高空間的使用效率,

在這里插入圖片描述

public static void countSort(int a[])
{
  int min=Integer.MAX_VALUE;int max=Integer.MIN_VALUE;
  for(int i=0;i<a.length;i++)//找到max和min
  {
    if(a[i]<min) 
      min=a[i];
    if(a[i]>max)
      max=a[i];
  }
  int count[]=new int[max-min+1];//對元素進行計數
  for(int i=0;i<a.length;i++)
  {
    count[a[i]-min]++;
  }
  //排序取值
  int index=0;
  for(int i=0;i<count.length;i++)
  {
    while (count[i]-->0) {
      a[index++]=i+min;//有min才是真正值
    }
  }
}

 



基數排序

基數排序是一種很容易理解但是比較難實作(優化)的演算法,基數排序也稱為卡片排序,基數排序的原理就是多次利用計數排序(計數排序是一種特殊的桶排序),但是和前面的普通桶排序和計數排序有所區別的是,基數排序并不是將一個整體分配到一個桶中,而是將自身拆分成一個個組成的元素,每個元素分別順序分配放入桶中、順序收集,當從前往后或者從后往前每個位置都進行過這樣順序的分配、收集后,就獲得了一個有序的數列,

image-20201113154119682

如果是數字型別排序,那么這個桶只需要裝0-9大小的數字,但是如果是字符型別,那么就需要注意ASCII的范圍,

所以遇到這種情況我們基數排序思想很簡單,就拿 934,241,3366,4399這幾個數字進行基數排序的一趟程序來看,第一次會根據各位進行分配、收集:

image-20201113161050871

分配和收集都是有序的,第二次會根據十位進行分配、收集,此次是在第一次個位分配、收集基礎上進行的,所以所有數字單看個位十位是有序的,

image-20201113161752292

而第三次就是對百位進行分配收集,此次完成之后百位及其以下是有序的,

image-20201113162803486

而最后一次的時候進行處理的時候,千位有的數字需要補零,這次完畢后后千位及以后都有序,即整個序列排序完成,

image-20201113170715860

簡單實作代碼為:

static void radixSort(int[] arr)//int 型別 從右往左
{
  List<Integer>bucket[]=new ArrayList[10];
  for(int i=0;i<10;i++)
  {
    bucket[i]=new ArrayList<Integer>();
  }
  //找到最大值
  int max=0;//假設都是正數
  for(int i=0;i<arr.length;i++)
  {
    if(arr[i]>max)
      max=arr[i];
  }
  int divideNum=1;//1 10 100 100……用來求對應位的數字
  while (max>0) {//max 和num 控制
    for(int num:arr)
    {
      bucket[(num/divideNum)%10].add(num);//分配 將對應位置的數字放到對應bucket中
    }
    divideNum*=10;
    max/=10;
    int idx=0;
    //收集 重新撿起資料
    for(List<Integer>list:bucket)
    {
      for(int num:list)
      {
        arr[idx++]=num;
      }
      list.clear();//收集完需要清空留下次繼續使用
    }
  }
}

 



當然,基數排序還有字串等長、不等長、一維陣列優化等各種實作需要需學習

 

有完整的Java初級,高級對應的學習路線和資料!專注于java開發,分享java基礎、原理性知識、JavaWeb實戰、spring全家桶、設計模式、分布式及面試資料、開源專案,助力開發者成長!


歡迎關注微信公眾號:碼邦主

 


作者:小林啊
鏈接:https://juejin.cn/post/6901528375023730701
來源:掘金

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/229364.html

標籤:其他

上一篇:kafka監聽出現的問題,解決和剖析

下一篇:Tcl技巧與bug匯總

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more