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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

七大排序速查版

發布時間:2024/4/17 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 七大排序速查版 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

通用結構體:

View Code typedef struct
{
int r[MAXSIZE+1]; //下標從1開始用,0為哨兵或其他用
int length;
}SqList;



一.選擇排序

1.1簡單選擇排序:

(1)思路:

通過n-i次關鍵字比較,從n-i+1個記錄中選出關鍵字最小的記錄,并和第i個記錄交換.

(2)代碼:

View Code void SelectSort(Sqlist *L)
{
int i, j, min;
for(i=1; i<L->length; i++)
{
for(j=i+1; j<L->length; j++)
{
min = i;
if(L->r[j] < L->r[min])
min = j;
}
if(i != min)
swap(L,i,min);
}

}

?

(3)時間復雜度:

由兩個for循環知,時間復雜度為(n^2).

?

1.2堆排

(1)相關定義:

堆是一種完全二叉樹,當結點值>=其左右孩子結點時,為大頂堆;反之,小頂堆.

(2)產生背景:

由簡單排序改良而來.簡單選擇排序第1次從n個數中取最小需要n-1次比較,但第2次從n-1個中選又要n-1-1次比較,沒利用好之前的比較.堆排則利用了,體現在建完大頂堆后,結點值大于孩子結點,所以重新調整時,比較的次數就大大縮減.

(3)使用步驟:

1.先建大頂堆 2.輸出最大值并重調

(4)代碼:

View Code //從上往下調整,使得L->r[s..m]滿足大頂堆的定義
void HeapAdjust(SqList *L, int s, int m)
{
int temp, j;
temp = L->r[s];
for(j=2*s; j<m; j*=2)
{
if(j<m && L->r[j]<L->r[j+1])
j++;
if(temp > L->r[s])
break;
L->r[s] = L->r[j];
s = j;
}
L->r[s] = temp;
}

void HeapSort(SqList *L)
{
int i;
for(i=L->length/2; i>0; i--)
{
HeapAdjust(L,i,L->length); //從下往上,從右往左調,這樣for循環結束后,堆已變成大頂堆;
}

for(i=L->length; i>0; i--)
{
swap(L,1,i); //輸出堆頂元素,然后將最后一個與其交換
HeapAdjust(L,1,i-1); //從新調整堆;
}
}

?

(5)時間復雜度

由完全二叉樹性質知,深度為log2n +1,即調用一次調整要logn時間,而堆排要調用n-1次,所以時間復雜度為(nlogn).

?

二.交換排序

2.1冒泡排序

(1)思路:

從下往上冒泡,每次都將最小的冒到最上,即第i次則將第i小的數冒泡到第i個位置上

(2)代碼:

View Code

?

(3)事件復雜度:

由兩個for循環可知,時間復雜度為(n^2).

?

2.2快排

(1)思路:

基于分治策略,將一個大的序列按某個值比較,按值大于或小于篩選分成兩個小的序列,然后按之前的原則分別再繼續細分,直到長度為1則排序完成.

(2)代碼:

View Code int Partion(SqList *L, int low, int high)
{
int pivot;
pivot = L->r[low]; //為達到更高效率,比較好的是取頭,尾,中三個數中第二大的數為'樞軸值'
if(low < high)
{
while(low<high && L->r[high]>=pivot)
high--;
L->r[row] = L->r[high];

while(low<high && L->r[low]<=pivot)
low++;
L->r[high] = L->r[low];
}
L->r[low] = pivot;
return low; //返回'樞軸值'
}

void QuikSort(SqList *L, int low, int high)
{
int pivot;
if(low < high)
{
pivot = partion(L,low,high); //將原序列一份為二
QuikSort(L,low,pivot); //遞歸調用左邊區間
QuikeSort(L,pivot+1,high); //遞歸調用右區間
}
}

?

(3)時間復雜度

最優情況為:樞軸值為序列中第n/2大的樹,則有:

T(n) = 2T(n/2) + f(n)??? //f(n)為將一個序列劃分為更小的序列所需的時間,這里f(n)=n

用主方法可知,時間復雜度為(nlogn).

最差情況為:序列為從小到大排好的,而且樞軸值為第一個,則退化為冒泡排序,時間復雜度為(n^2).

?

三.插入排序

3.1直接插入排序

(1)思路:

將一個記錄插入到已經排好序的有序序列中,從而得到一個新的記錄數加1的有序序列.

(2)代碼:

View Code void InsertSort(SqList *L)
{
int i,j;
for(i=2; i<L->length; i++)
{
if(L->r[i] < L->r[i-1]) //將L->r[i]插入到有序序列中
{
L->r[0] = L->r[i]; //哨兵,暫存值
for(j=i-1; L->r[j]>L->r[0]; j--)
{
L->r[j+1] = L->r[j]; //比L->r[i]大的,向后挪,騰出位子來
}
L->r[j+1] = L->r[0]; //j+1是由于for循環最后多減了1
}

}
}

?

(3)時間復雜度:(n^2).

?

3.2希爾排序

(1)思路:

直接插入排序的改良版.先用比較大的間隔的數去使用插入排序,然后逐步縮減間隔大小,直到為1.即讓序列每次排序后越來越接近有序序列.

(2)代碼:

View Code void ShellSort(SqList *L)
{
int i, j;
int increment = L->length;
while(increment>1)
{
increment = increment/3 +1; //相對來說比較好的一個間隔數
for(i=increment+1; i<=L->length; i++)
{
if(L->r[i] < L->r[i-increment])
{
L->r[0] = L->r[i];
for(j=i-increment; L->r[j]>L->r[0]; j=j-increment)
{
L->r[j+increment] = L->r[j];
}
L->r[j+increment] = L->r[0];
}
}
}
}

?

(3)時間復雜度:

大量的研究表明,當增量序列為dlta[k]=2t-k+1-1(0≤k≤t≤?log2(n+1)?)時,可以獲得不錯的效率,其時間復雜度為O(n3/2),要好于直接排序的O(n2)。

?

四.歸并排序

歸并排序

(1)思路:

典型的分治策略,分而治之,分到1個1個,再兩兩合并成有序序列.

(2)步驟:

需要一個臨時數組來裝分出來的兩個序列.

(2)代碼:

View Code void MergeSort(SqList *L)
{
MSort(L->r, L->r, 1, L->length);
}

void MSort(int SR[],int TR1[], int s, int t) //將SR[s..t]歸并排序為TR1[s..t]
{
int m;
int TR2[MAXSIZE+1]; //臨時數組,用來在相鄰遞歸函數之間傳遞數據

if(s==t) //3遞歸結束條件,即每個數組只有一個元素
TR1[s] = SR[s];
else
{
m = (s+t)/2; //1平分SR,然后從兩個序列中繼續遞歸調用
MSort(SR,TR2,s,m);
MSort(SR,TR2,m+1,t);
Merge(TR2,TR1,s,m,t); //2將TR2[s..m]和TR2[m+1..t]合并到TR1[s..t]中

}
}

void Merge(int SR[], int TR[], int i, int m, int n)
{
int j, k, l;
for(k=i,j=m+1; (i<=m)&&(j<=n); k++)
{
if(SR[i]<SR[j])
TR[K] = SR[i++];
else
TR[K] = SR[j++];
}

//跳出for循環則說明有一組已經全部插入TR[]中,所以將剩下的全部復制到TR[]后面即可
if(i<=m) //i<=m,則說明j>n即j已經插完
for(l=1; l<=m; l++)
TR[k+1] = SR[i+1];

if(j<=n)
for(l=1; l<=n; l++)
TR[k+1] = SR[j+1];
}

?

(3)時間復雜度:

T(n) = 2T(n/2) + n-1??? //n-1為將n個數分成一個一個以及兩兩合并的時間,由于n個要比較n-1次

由主方法可知,時間復雜度為(nlogn).

轉載于:https://www.cnblogs.com/Quains/archive/2012/04/03/2430607.html

總結

以上是生活随笔為你收集整理的七大排序速查版的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。