亚洲综合图片区自拍_思思91精品国产综合在线观看_一区二区三区欧美_欧美黑人又粗又大_亚洲人成精品久久久久桥本

常見排序功能的實(shí)現(xiàn)

2022-12-06 18:16:23 來(lái)源:51CTO博客

#include

#include


【資料圖】

#include

#include

#include

#include

using namespace std;

// a和b數(shù)值進(jìn)行交換

Swap(int& a,int& b){

if (a==b)return;

int k=a;

a=b;

b=k;

}

/*******************************1、冒泡排序****************************/

//原理:依次比較相鄰的2個(gè)數(shù),將比較小的數(shù)放在前面,比較大的數(shù)放在后面

BubbleSort(int arrNum[], int nSize){

int i=0;

int j=0;

int n=nSize;//數(shù)組含有元素的個(gè)數(shù)

//如果數(shù)組個(gè)數(shù)少于2個(gè),沒有必要比較,直接退出

if(n<=1)return;

for (i=0;i

//n-i-1是每輪比較的最大次數(shù);因?yàn)橄聵?biāo)j+1要小于數(shù)組的最大下標(biāo),所以還要-1

for (j=0;j

Swap(arrNum[j],arrNum[j+1]);

}

}

}

/**************************2、選擇排序******************************/

//原理:每次從待排序的數(shù)據(jù)元素中選出最小(或者最大)的一個(gè)元素,存放在已排好序列的起始位置(或者末尾位置), 直到全部待排序

SelectionSort(int arrNum[],int nSize){

int i=0;

int j=0;

int n=nSize;

if (n<=1)return;

for (i=0;i

int pos=i;//pos記錄值最小的數(shù)組下標(biāo)位置

for (j=i;j

if (arrNum[pos]>arrNum[j])

pos=j;

}

Swap(arrNum[i],arrNum[pos]);

}

}

/*********************3、直接插入排序******************************/

//原理:是將無(wú)序序列中的數(shù)據(jù)插入到有序的序列中,在遍歷無(wú)序序列時(shí),首先拿無(wú)序序列中的首元素去與有序序列中的每一個(gè)元素比較并插入到合適的位置,一直到無(wú)序序列中的所有元素插完為止。

InsertionSort(int arrNum[], int nSize){

int i=0;

int j=0;

int n=nSize;

if (n<=1)return;

for (i=0;i

for (j=i+1;j

Swap(arrNum[i],arrNum[j]);

}

}

}

/***********************************4、希爾排序***********************/

//原理:是把序列按下標(biāo)的一定增量分組,對(duì)每組使用直接插入排序算法排序;隨著增量的逐漸減少,每組包含的關(guān)鍵詞越來(lái)越多,當(dāng)增量減至1時(shí),整個(gè)序列恰好被分為一組,算法便終止。

//分組增量gap=length/2,縮小增量以gap=gap/2

ShellSort(int arrNum[], int nSize){

int j=0;

int i=0;

int n=nSize;

int gap=n/2;

if (n<=1 || gap<1)return;

while (gap>0){

for (i=0;i

for (j=i+gap;j

Swap(arrNum[i],arrNum[j]);

}

}

gap=gap/2;

}

}

/****************************5、歸并排序******************************/

//原理算法:先把數(shù)據(jù)組分成一半,再把左邊的數(shù)組再分一半排序,右邊的數(shù)組再分一半,一直分到只有2個(gè)有序數(shù)為至,然后再歸并

MergeSort(int arrNum[], int low,int high){

int i=0;

int j=0;

int k=0;

int n=0;

int half=low+(high-low)/2;

//不能再分的條件,high是當(dāng)前數(shù)組的個(gè)數(shù),不是最大元素的下標(biāo)

if (low>=(high-1))return;

//先分

MergeSort(arrNum,low,half);

MergeSort(arrNum,half,high);

//再合

//臨時(shí)開辟動(dòng)態(tài)數(shù)組

n=high-low;

int* pArray=(int*)malloc(n*sizeof(int));

memset(pArray,0,n*sizeof(int));

i=0;

j=low;

k=half;

while(j

if (arrNum[j]>arrNum[k])

pArray[i++]=arrNum[k++];

else

pArray[i++]=arrNum[j++];

}

while(j

pArray[i++]=arrNum[j++];

while(k

pArray[i++]=arrNum[k++];

for (i=0;i

arrNum[low++]=pArray[i];

free(pArray);

}

/*********************6、快速排序*******************************/

//選擇一個(gè)基準(zhǔn)數(shù),通過(guò)一趟排序?qū)⒁判虻臄?shù)據(jù)分割成獨(dú)立的兩部分;其中一部分的所有數(shù)據(jù)都比另外一部分的所有數(shù)據(jù)都要小。

//然后,再按此方法對(duì)這兩部分?jǐn)?shù)據(jù)分別進(jìn)行快速排序,整個(gè)排序過(guò)程可以遞歸進(jìn)行,以此達(dá)到整個(gè)數(shù)據(jù)變成有序序列。

QuickSort(int arrNum[], int low,int high){

int i=low;

int j=high-1;

int nBase=arrNum[low];

//遞歸中止條件

if (i>=j)return;

//基準(zhǔn)數(shù)選取當(dāng)前數(shù)組區(qū)間的第1個(gè)元素

while(true){

//從后向前掃描,找小于基準(zhǔn)數(shù)的值,然后放到下標(biāo)為i的位置

while(i

if(nBase<=arrNum[j])

j--;

else{

arrNum[i]=arrNum[j];

break;

}

}

//從前向后掃描,找大于基準(zhǔn)數(shù)的值,然后放到下標(biāo)為j的位置

while(i

if(nBase>arrNum[i])

i++;

else{

arrNum[j]=arrNum[i];

break;

}

}

if (i==j){

arrNum[i++]=nBase;

break;

}

}

QuickSort(arrNum,low,i);

QuickSort(arrNum,i,high);

}

//建立大堆

//堆是一種非線性結(jié)構(gòu),可以把堆看作一個(gè)數(shù)組,也可以被看作一個(gè)完全二叉樹,通俗來(lái)講堆其實(shí)就是利用完全二叉樹的結(jié)構(gòu)來(lái)維護(hù)的一維數(shù)組但堆并不一定是完全二叉樹

//按照堆的特點(diǎn)可以把堆分為大頂堆和小頂堆

//大頂堆:每個(gè)結(jié)點(diǎn)的值都大于或等于其左右孩子結(jié)點(diǎn)的值

//小頂堆:每個(gè)結(jié)點(diǎn)的值都小于或等于其左右孩子結(jié)點(diǎn)的值

//二叉數(shù),設(shè)深度為h(根節(jié)點(diǎn)層數(shù)為0),某個(gè)父節(jié)點(diǎn)為dad,子節(jié)點(diǎn)為son,有以下特點(diǎn):

//滿二叉數(shù): 總節(jié)點(diǎn)數(shù)是:2^(h+1)-1,第k層節(jié)點(diǎn)數(shù)是:2^k

//完全二叉數(shù):第k層節(jié)點(diǎn)數(shù)是:2^k

//父和子節(jié)點(diǎn)的2個(gè)元素序號(hào)關(guān)系:dad=son*2+1,dad=son*2+2

MaxHeap(int arrNum[], int start,int tail){

int dad=0; //存放父節(jié)點(diǎn)序號(hào)

int son=0; //存放子節(jié)點(diǎn)序號(hào)

dad=start;

son=dad*2+1;//左孩子節(jié)點(diǎn)

//當(dāng)有孩子節(jié)點(diǎn)時(shí)

while(son<=tail){

//當(dāng)同時(shí)存在2個(gè)子節(jié)點(diǎn)時(shí),先比較2個(gè)子節(jié)點(diǎn)值的大小,選擇值最大的節(jié)點(diǎn)

if (son+1<=tail){

if (arrNum[son]

son=son+1;

}

//如果父節(jié)點(diǎn)的值大于子節(jié)點(diǎn)(最大值的子節(jié)點(diǎn))時(shí),直接返回

if (arrNum[dad]>arrNum[son])return;

//如果父節(jié)點(diǎn)的值小于子節(jié)點(diǎn)的值時(shí),交換位置

Swap(arrNum[dad],arrNum[son]);

//使當(dāng)前子節(jié)點(diǎn)成為父節(jié)點(diǎn),往下繼續(xù)查找比較建立大堆

dad=son;

son=dad*2+1;

}

}

/*************************7、堆排序**********************************/

//原理:堆排序是利用堆這種數(shù)據(jù)結(jié)構(gòu)而設(shè)計(jì)的一種排序算法,堆排序是一種選擇排序,它的最壞,最好,平均時(shí)間復(fù)雜度均為O(nlogn),它也是不穩(wěn)定排序,首先簡(jiǎn)單了解下堆結(jié)構(gòu)

HeapSort(int arrNum[], int nSize){

int i=0;

int j=0;

int k=0;

//初始化構(gòu)建一個(gè)完全二叉數(shù),方法是:(length/2-1)為最后一個(gè)父節(jié)點(diǎn),從當(dāng)前父節(jié)點(diǎn)往下構(gòu)建大堆,然后循環(huán)一直到根節(jié)點(diǎn)

i=nSize/2-1;

for (i;i>=0;i--)

MaxHeap(arrNum,i,nSize-1);

//從最后一個(gè)元素開始向上查找,將第一個(gè)元素和已經(jīng)排好的元素前一位交換,

//再重新調(diào)整,構(gòu)建小堆,直到排序完畢

for (i=nSize-1;i>0;i--)

{

Swap(arrNum[0],arrNum[i]);

MaxHeap(arrNum,0,i-1);

}

}

/*************************8、計(jì)數(shù)排序*****************************/

//一步:找出原數(shù)組中元素值最大的,記為max。

//第二步:創(chuàng)建一個(gè)新數(shù)組count,其長(zhǎng)度是max加1,其元素默認(rèn)值都為0。

//第三步:遍歷原數(shù)組中的元素,以原數(shù)組中的元素作為count數(shù)組的索引,以原數(shù)組中的元素出現(xiàn)次數(shù)作為count數(shù)組的元素值。

//第四步:創(chuàng)建結(jié)果數(shù)組result,起始索引index。

//第五步:遍歷count數(shù)組,找出其中元素值大于0的元素,將其對(duì)應(yīng)的索引作為元素值填充到result數(shù)組中去,每處理一次,count中的該元素值減1,直到該元素值不大于0,依次處理count中剩下的元素。

//第六步: 返回結(jié)果數(shù)組result?

CountSort(int arrNum[], int nSize){

int i=0;

int j=0;

int min=0;

int max=0;

int n=0;

int* pArray=NULL;

min=arrNum[0];

max=min;

for (i=1;i

if(min>arrNum[i])

min=arrNum[i];

if(max

max=arrNum[i];

}

n=max-min+1; //準(zhǔn)備開辟的動(dòng)態(tài)數(shù)組的空間

pArray=new int[n];//申請(qǐng)動(dòng)態(tài)數(shù)組

memset(pArray,0,sizeof(arrNum[0])*n);

//計(jì)數(shù)排序第1種計(jì)算方法

// for (i=0;i

// pArray[arrNum[i]-min]++;

// for (j=0,i=0;i

// {

// while (pArray[i]-->0)

// arrNum[j++]=i+min;

// }

//計(jì)數(shù)排序第2種計(jì)算方法

//需要在創(chuàng)建一個(gè)臨時(shí)數(shù)組,和原數(shù)組大小一樣

int* pArrayTemp=new int[nSize];

//哪個(gè)位置有值,標(biāo)記為1,如果有多個(gè)值,每次+1

for (i=0;i

pArray[arrNum[i]-min]++;

//構(gòu)建計(jì)數(shù)數(shù)組

for (i=1;i

pArray[i]+=pArray[i-1];

//把排序的結(jié)果數(shù)據(jù)臨時(shí)存放到臨時(shí)數(shù)組pArraytemp中

for (i=0;i

//作為pArray的下標(biāo)[arrNum[i]-min]

int index=arrNum[i]-min;

pArrayTemp[pArray[index]-1]=arrNum[i];

pArray[index]--;

}

for (i=0;i

arrNum[i]=pArrayTemp[i];

delete[] pArrayTemp;

pArrayTemp=NULL;

delete[] pArray;//釋放動(dòng)態(tài)數(shù)組空間

pArray=NULL;

}

/***************************9、桶排序**********************************/

//原理:桶排序是計(jì)數(shù)排序的擴(kuò)展版本,計(jì)數(shù)排序可以看成每個(gè)桶只存儲(chǔ)相同元素,而桶排序每個(gè)桶存儲(chǔ)一定范圍的元素,通過(guò)映射函數(shù),將待排序數(shù)組中的元素映射到各個(gè)對(duì)應(yīng)的桶中,

//對(duì)每個(gè)桶中的元素進(jìn)行排序,最后將非空桶中的元素逐個(gè)放入原序列中。

BucketSort(int arrNum[], int nSize){

int i=0;

int j=0;

int n=0; //記錄桶的個(gè)數(shù)

int max=arrNum[0];

int min=arrNum[0];

//確認(rèn)桶的個(gè)數(shù),公式: (最大值-最小值)/數(shù)組長(zhǎng)度

for (i=1;i

if (arrNum[i]

min=arrNum[i];

if (arrNum[i]>max)

max=arrNum[i];

}

n=(max-min)/nSize+1; //桶的個(gè)數(shù)

vector * pVector=new vector[n];

for(i=0;i

vector v;

pVector[i]=v;

}

for(i=0;i

int index=(arrNum[i]-min)/nSize;

pVector[index].push_back(arrNum[i]);

}

for(i=0;i

if (pVector[i].size()>0)

sort(pVector[i].begin(),pVector[i].end());

}

for (j=0,i=0;i

if(pVector[i].size()>0){

vector::iterator it=pVector[i].begin();

for(it;it!=pVector[i].end();++it){

arrNum[j++]=*it;

}

}

}

delete[] pVector;

pVector=NULL;

}

/***************************10、基數(shù)排序*************************/

//它是這樣實(shí)現(xiàn)的:將所有待比較數(shù)值(正整數(shù))統(tǒng)一為同樣的數(shù)位長(zhǎng)度,數(shù)位較短的數(shù)前面補(bǔ)零。然后,從最低位開始,依次進(jìn)行一次排序。這樣從最低位排序一直到最高位排序完成以后, 數(shù)列就變成一個(gè)有序序列。

RadixSort(int arrNum[], int nSize){

int i=0;

int j=0;

int n=0;//記錄循環(huán)次數(shù)

int arrCount[10]={0}; //記錄每個(gè)數(shù)當(dāng)前位的數(shù)字的數(shù)組

int nRadix=0;

int* pArray=NULL;

//獲取數(shù)組中最大的數(shù)值

for (i=0;i

n=(arrNum[i]>n)?arrNum[i]:n;

//獲取最大數(shù)的位數(shù)

i=n,n=0;

while(i>0){

i=i/10;

n++;

}

pArray=new int[nSize];

i=0,nRadix=1;

while(i

for (j=0;j

int index=(arrNum[j]/nRadix)%10;//獲取當(dāng)前位的數(shù)字

arrCount[index]++;

}

for (j=1;j<10;j++){

arrCount[j]+=arrCount[j-1];

}

memset(pArray,0,sizeof(int)*nSize);

for (j=nSize-1;j>=0;j--){

int index=(arrNum[j]/nRadix)%10;//獲取當(dāng)前位的數(shù)字

pArray[arrCount[index]-1]=arrNum[j];

arrCount[index]--;

}

for (j=0;j

arrNum[j]=pArray[j];

}

memset(arrCount,0,40);

nRadix=nRadix*10;

i++;

}

delete[] pArray;

}

標(biāo)簽: 動(dòng)態(tài)數(shù)組 完全二叉樹

上一篇:Spring for GraphQL入門
下一篇:喝汽水--C語(yǔ)言