久久99精品久久久久久琪琪,久久人人爽人人爽人人片亞洲,熟妇人妻无码中文字幕,亚洲精品无码久久久久久久

用php實現(xiàn)的各種排序算法總結(jié)

時間:2019-05-12 04:37:05下載本文作者:會員上傳
簡介:寫寫幫文庫小編為你整理了多篇相關(guān)的《用php實現(xiàn)的各種排序算法總結(jié)》,但愿對你工作學(xué)習(xí)有幫助,當然你在寫寫幫文庫還可以找到更多《用php實現(xiàn)的各種排序算法總結(jié)》。

第一篇:用php實現(xiàn)的各種排序算法總結(jié)

www.tmdps.cn 用php實現(xiàn)的各種排序算法總結(jié)

優(yōu)化php性能的五個實用技巧:

以下是五個優(yōu)化技巧,熟練掌握后對于開發(fā)還是很有幫助的。

1.對字符串使用單引號

PHP 引擎允許使用單引號和雙引號來封裝字符串變量,但是這個是有很大的差別的!使用雙引號的字符串告訴 PHP 引擎首先去讀取字符串內(nèi)容,查找其中的變量,并改為變量對應(yīng)的值。一般來說字符串是沒有變量的,所以使用雙引號會導(dǎo)致性能不佳。最好是使用字符串連接而不 是雙引號字符串。

BAD:

$output = “This is a plain string”;

GOOD:

$output = 'This is a plain string';

BAD:

$type = “mixed”;

$output = “This is a $type string”;

GOOD:

$type = 'mixed';

$output = 'This is a '.$type.' string';

2.不要隨便就復(fù)制變量

有時候為了使 PHP 代碼更 加整潔,一些 PHP 新手(包括我)會把預(yù)定義好的變量復(fù)制到一個名字更簡短的變量中,其實這樣做的結(jié)果是增加了一倍的內(nèi)存消耗,只會使程序更加慢。試想一下,在下面的例子 中,如果用戶惡意插入 512KB 字節(jié)的文字到文本輸入框中,這樣就會導(dǎo)致 1MB 的內(nèi)存被消耗!

BAD:

$description = $_POST['description'];shishicaimh.com www.tmdps.cn

echo $description;

GOOD:

echo $_POST['description'];

3.使用 echo 函數(shù)來輸出字符串

使用 echo()函數(shù)來打印結(jié)果出了有更容易閱讀之外,在下個例子中,你還可以看到有更好的性能。

BAD:

print($myVariable);

GOOD:

echo $myVariable;

4.不要在 echo 中使用連接符

很***PHP 程序員(有包括我)不知道在用 惡臭 輸出多個變量的時候,其實可以使用逗號來分開的,而不必用字符串先把他們先連起來,如下面的第一個例子中,由于使用了連接符就會有性能問題,因為這樣就會 需要 PHP 引擎首先把所有的變量連接起來,然后在輸出,而在第二個例子中,PHP 引擎就會按照循序輸出他們。

BAD:

echo 'Hello, my name is'.$firstName.$lastName.' and I live in '.$city;

GOOD:

echo 'Hello, my name is' , $firstName , $lastName , ' and I live in ' , $city;

5.使用 switch/case 代替 if/else

對于只有單個變量的判斷,使用 switch/case 語句而不是 if/else 語句,會有更好的性能,并且代碼更加容易閱讀和維護。

BAD:

if($_POST['action'] == 'add‘){

shishicaimh.com www.tmdps.cn

addUser();

} elseif($_POST['action'] == 'delete’){

deleteUser();

} elseif($_POST['action'] == 'edit‘){

editUser();

} else {

defaultAction();

}

GOOD:

switch($_POST['action']){

case 'add':

addUser();

break;

case 'delete':

用php實現(xiàn)的各種排序算法,冒泡排序,交換排序,選擇法排序,插入法排序,快速排序,根據(jù)實際情況可選則不同的排序算法。效率也有所不同。

冒泡排序:

function BubbleSort($arr){

$num = count($arr);

for($i=1;$i<$num;$i++){

for($j=$num-1;$j>=$i;$j--){

if($arr[$j]<$arr[$j-1]){

$iTemp = $arr[$j-1];

$arr[$j-1] = $arr[$j];

$arr[$j] = $iTemp;

}

}

}

return $arr;

}

?> shishicaimh.com www.tmdps.cn

交換法排序:

function ExchangeSort($arr){

$num = count($arr);

for($i=0;$i<$num-1;$i++){

for($j=$i+1;$j<$num;$j++){

if($arr[$j]<$arr[$i]){

$iTemp = $arr[$i];

$arr[$i] = $arr[$j];

$arr[$j] = $iTemp;

}

}

}

return $arr;

}

?>

選擇法排序:

function SelectSort($arr){

$num = count($arr);

for($i=0;$i<$num-1;$i++){

$iTemp = $arr[$i];

$iPos = $i;

for($j=$i+1;$j<$num;$j++){

if($arr[$j]<$iTemp){

$iTemp = $arr[$j];

$iPos = $j;

}

}

$arr[$iPos] = $arr[$i];

$arr[$i] = $iTemp;

}

return $arr;

}

?>

插入法排序:

function InsertSort($arr){

$num = count($arr);

for($i=1;$i<$num;$i++){

$iTemp = $arr[$i];

$iPos = $i-1;

while(($iPos>=0)&&($iTemp<$arr[$iPos])){

$arr[$iPos+1] = $arr[$iPos];

$iPos--;

}

$arr[$iPos+1] = $iTemp;shishicaimh.com www.tmdps.cn

}

return $arr;

}

?>

快速排序 :

function QuickSort($arr){

$num = count($arr);

$l=$r=0;

for($i=1;$i<$num;$i++){

if($arr[$i] < $arr[0]){

$left[] = $arr[$i];

$l++;

}else{

$right[] = $arr[$i];

$r++;

}

}

if($l > 1){

$left = QuickSort($left);

}

$new_arr = $left;

$new_arr[] = $arr[0];

if($r > 1){

$right = QuickSort($right);

}

for($i=0;$i<$r;$i++){

$new_arr[] = $right[$i];

}

return $new_arr;

}

$arr = array(7,1,6,5,2);

$arr_new = QuickSort($arr);

?>

deleteUser();

break;

case 'edit':

editUser();

break;

default: shishicaimh.com

第二篇:C++ 八種排序算法總結(jié)及實現(xiàn)

八種排序算法總結(jié)之C++版本

五種簡單排序算法

一、冒泡排序

【穩(wěn)定的】

void BubbleSort(int* a,int Count)//實現(xiàn)從小到大的最終結(jié)果 { int temp;for(int i=1;i

for(int j=Count-1;j>=i;j--)

if(a[j] < a[j-1])

{

temp = a[j];

a[j] = a[j-1];

a[j-1] = temp;

} }

現(xiàn)在注意,我們給出O方法的定義:

若存在一常量K和起點n0,使當n>=n0時,有f(n)<=K*g(n),則f(n)= O(g(n))。(呵呵,不要說沒學(xué)好數(shù)學(xué)呀,對于編程數(shù)學(xué)是非常重要的!!)

現(xiàn)在我們來看1/2*(n-1)*n,當K=1/2,n0=1,g(n)=n*n時,1/2*(n-1)*n<=1/2*n*n=K*g(n)。所以f(n)=O(g(n))=O(n*n)。所以我們程序循環(huán)的復(fù)雜度為O(n*n)。

二、交換排序

【穩(wěn)定的】

void ExchangeSort(int *a,int Count){ int temp;for(int i=0;i

for(int j=i+1;j

if(a[j] < a[i])

{

temp = a[j];

a[j] = a[i];

a[i] = temp;

} }

時間復(fù)雜度為O(n*n)。

三、選擇法

【不穩(wěn)定的】

void SelectSort(int *a,int Count){ int temp;//一個存儲值

int pos;//一個存儲下標

for(int i=0;i

temp = a[i];

pos = i;

for(int j=i+1;j

if(a[j] < temp)//選擇排序法就是用第一個元素與最小的元素交換

{

temp = a[j];

pos = j;//下標的交換賦值,記錄當前最小元素的下標位置

}

a[pos] = a[i];

a[i] = temp;} }

遺憾的是算法需要的循環(huán)次數(shù)依然是1/2*(n-1)*n。所以算法復(fù)雜度為O(n*n)。

我們來看他的交換。由于每次外層循環(huán)只產(chǎn)生一次交換(只有一個最小值)。所以f(n)<=n 所以我們有f(n)=O(n)。所以,在數(shù)據(jù)較亂的時候,可以減少一定的交換次數(shù)。

四、插入法

【穩(wěn)定的】

void InsertSort(int *a,int Count){ int temp;//一個存儲值

int pos;//一個存儲下標

for(int i=1;i

{

temp = a[i];//當前要插入的元素

pos = i-1;

while(pos>=0 && temp

{

a[pos+1] = a[pos];//將前一個元素后移一位

pos--;

}

a[pos+1] = temp;} }

其復(fù)雜度仍為O(n*n)。

最終,我個人認為,在簡單排序算法中,直接插入排序是最好的。

五、希爾排序法

【不穩(wěn)定的】 /* * 希爾排序,n為數(shù)組的個數(shù) */ void ShellSort(int arr[], int n){ int temp,pos;int d = n;//增量初值

do{

d = d/3 + 1;

for(int i= d;i

{

temp = arr[i];

pos = i-d;

while(pos>=0 && temp < arr[pos]){

arr[ pos + d ] = arr[pos];

pos-= d;

}

arr[ pos + d ] = temp;

} } while(d > 1);}

//實現(xiàn)增量為d的插入排序

三種高級排序算法

一、快速排序

輔助空間復(fù)雜度為O(1)

【不穩(wěn)定的】 void QuickSort(int *a,int left, int right){ int i,j,middle,temp;i = left;j = right;middle = a[(left+right)/2 ];do {

while(a[i]

i++;

while(a[j]>middle && j>left)//從右掃描小于中值的數(shù)

j--;

if(i<=j)//找到了一對值

{

temp = a[i];

a[i] = a[j];

}

a[j] = temp;

i++;

j--;}

} while(ii),遞歸右半邊 if(i < right)QuickSort(a, i, right);它的工作看起來象一個二叉樹。首先我們選擇一個中間值middle,程序中我們使用數(shù)組中間值,然后把比它小的放在左邊,大的放在右邊(具體的實現(xiàn)是從兩邊找,找到一對后交換)。然后對兩邊分別使用這個過程(最容易的方法——遞歸)。注意,由于數(shù)據(jù)的隨機性,對middle的選擇并不會影響該算法的效率。

注意,在掃描過程中,對于給定參考值,對于向右(左)掃描,如果掃描值大(小)于或等于參考值,就需要進行交換。最終得到的結(jié)果是,j左邊的值都小于參考值,而i右邊的值都大于參考值,j和i之間的值都等于參考值。對j左邊和i右邊的分別使用遞歸,就可以完成最終的排序。

這里我沒有給出行為的分析,因為這個很簡單,我們直接來分析算法:首先我們考慮最理想的情況

1.數(shù)組的大小是2的冪,這樣分下去始終可以被2整除。假設(shè)為2的k次方,即k=log2(n)。

2.每次我們選擇的值剛好是中間值,這樣,數(shù)組才可以被等分。

第一層遞歸,循環(huán)n次,第二層循環(huán)2*(n/2)......所以共有n+2(n/2)+4(n/4)+...+n*(n/n)= n+n+n+...+n=k*n=log2(n)*n 所以算法復(fù)雜度為O(log2(n)*n)

其他的情況只會比這種情況差,最差的情況是每次選擇到的middle都是最小值或最大值,那么他將變

成交換法(由于使用了遞歸,情況更糟),但是糟糕的情況只會持續(xù)一個流程,到下一個流程的時候就很可能已經(jīng)避開了該中間的最大和最小值,因為數(shù)組下標變化了,于是中間值不在是那個最大或者最小值。但是你認為這種情況發(fā)生的幾率有多大??呵呵,你完全不必擔(dān)心這個問題。實踐證明,大多數(shù)的情況,快速排序總是最好的。

如果你擔(dān)心這個問題,你可以使用堆排序,這是一種穩(wěn)定的O(log2(n)*n)算法,但是通常情況下速度要慢

于快速排序(因為要重組堆)。

二、歸并排序(兩種實現(xiàn)方法均要掌握)

【穩(wěn)定的】

歸并排序是一種極好的外部排序方法,即針對數(shù)據(jù)保存在磁盤上而不是高速內(nèi)存中的問題。

//以下程序參考數(shù)據(jù)結(jié)構(gòu)課本P286頁的模板,為使用指針鏈表實現(xiàn)的 #include using namespace std;

struct node{ //鏈表的節(jié)點數(shù)據(jù)

int value;node *next;};

node * divide_from(node * head){ node * position, * midpoint, * second_half;if((midpoint=head)== NULL)//List is empty

return NULL;position = midpoint->next;while(position!= NULL)//Move position twice for midpoint's one move {

position = position->next;

if(position!= NULL)

{

midpoint = midpoint->next;

position = position->next;

}

} second_half = midpoint->next;midpoint->next = NULL;//在這里將原鏈拆斷,分為兩段

return second_half;}

node * merge(node * first, node * second){ node * last_sorted;//當前已經(jīng)鏈接好的有序鏈中的最后一個節(jié)點

node combined;//啞節(jié)點

last_sorted = &combined;while(first!=NULL && second!=NULL){

if(first->value < second->value){

last_sorted->next = first;

last_sorted = first;

first = first->next;

}else {

last_sorted->next = second;

last_sorted = second;

second = second->next;

} } if(first==NULL)

last_sorted->next = second;else

last_sorted->next = first;return combined.next;//返回啞節(jié)點的后繼指針,即為合并后的鏈表的頭指針 }

//這里的參數(shù)必須是引用調(diào)用,需要這個指引去允許函數(shù)修改調(diào)用自變量 void MergeSort(node * &head){ if(head!= NULL && head->next!= NULL)//如果只有一個元素,則不需排序 {

node * second_half = divide_from(head);

MergeSort(head);

MergeSort(second_half);

head = merge(head, second_half);} }

int main(){ node a,b,c,d;node *p1, *p2, *p3, *p4,*head;p1 = &a;p2 = &b;p3 = &c;p4 = &d;a.value = 2;b.value = 4;c.value = 3;d.value = 1;a.next = p2;b.next = p3;c.next = p4;d.next = NULL;//調(diào)用歸并排序前的結(jié)果

head = p1;while(head!= NULL){

cout<value<<“ ”;

head = head->next;} cout<

head = p1;while(head!= NULL){

cout<value<<“ ”;

head = head->next;} cout<

//以下程序為使用數(shù)組實現(xiàn)的歸并排序,輔助空間復(fù)雜度為O(n)

#include using namespace std;

void Merge(int data[], int left, int mid, int right){ int n1,n2,k,i,j;n1 = midmid;int *L = new int[n1];//兩個指針指向兩個動態(tài)數(shù)組的首地址

int *R = new int[n2];for(i=0,k=left;i

L[i] = data[k];for(i=0,k=mid+1;i

R[i] = data[k];for(k=left,i=0,j=0;i

if(L[i] < R[j]){ //取小者放前面

data[k] = L[i];

i++;

} else {

data[k] = R[j];

j++;

} } if(i

for(j=i;j < n1;j++,k++)

} /* * left:數(shù)組的開始下標,一般為0;right:數(shù)組的結(jié)束下標,一般為(n-1)*/

void MergeSort(int data[], int left, int right){ if(left < right){

int mid = left +(right-left)/ 2;//mid=(right+left)/2,防止溢出

MergeSort(data, left, mid);

MergeSort(data , mid+1, right);

Merge(data , left, mid , right);} }

int main(){ int data[] = {9,8,7,2,5,6,3,55,1};//排序前的輸出

for(int i=0;i<9;i++)

cout<

for(int i=0;i<9;i++)

cout<

三、堆排序 【不穩(wěn)定的】

/* * 向堆中插入current元素的函數(shù) */ void insert_heap(int data[], const int ¤t, int low, int high)

data[k] = L[j];else //if(j

for(i=j;i

data[k] = R[i];delete []L;//回收內(nèi)存 delete []R;{ int large;//元素data[low]左右兒子中,大者的位置

large = 2*low + 1;while(large <= high){

if(large < high && data[large] < data[ large+1])

large++;

if(current > data[ large ])//待插入元素的值比它的兩個兒子都大

break;

else {

data[ low ] = data[ large ];//將其左右兒子的大者上移

low = large;

large = 2 * large + 1;

} } data[ low ] = current;} /* * 建立堆函數(shù),num為數(shù)組data的元素個數(shù)

* 只有一個結(jié)點的<2-樹>自動滿足堆的屬性,因此不必擔(dān)心樹中的任何樹葉,即 * 不必擔(dān)心表的后一半中的元素。如果從表的中間點開始并從后向前工作,就 * 能夠使用函數(shù)insert_heap去將每個元素插入到包含了所有后面元素的部分堆 * 中,從而創(chuàng)建完整的堆。*/ void build_heap(int data[], int num){

int current;for(int low = num/2-1;low>=0;low--){

current = data[ low ];

insert_heap(data, current, low, num-1);} } /* * 堆排序主函數(shù),num為數(shù)組data的元素個數(shù) */ void heap_sort(int data[], int num){ int current, last_sorted;build_heap(data, num);//建立堆

for(last_sorted = num-1;last_sorted>0;last_sorted--){ //逐個元素處理

current = data[ last_sorted ];//data[0]在整個數(shù)組排序結(jié)束前,存儲的是待排序元素中最大的元素

data[last_sorted] = data[0];

insert_heap(data, current, 0, last_sorted-1);} } int main(){ //用于排序算法的輸入輸出

int a[8] = {5,7,1,2,9,4,6,3,};for(int i=0;i< sizeof(a)/sizeof(int);i++)

cout<

for(int i=0;i< sizeof(a)/sizeof(int);i++)

cout<

第三篇:排序算法總結(jié)

排序算法總結(jié)

所謂排序,就是要整理文件中的記錄,使之按關(guān)鍵字遞增(或遞減)次序排列起來。當待排序記錄的關(guān)鍵字都不相同時,排序結(jié)果是惟一的,否則排序結(jié)果不惟一。

在待排序的文件中,若存在多個關(guān)鍵字相同的記錄,經(jīng)過排序后這些具有相同關(guān)鍵字的記錄之間的相對次序保持不變,該排序方法是穩(wěn)定的;若具有相同關(guān)鍵字的記錄之間的相對次序發(fā)生改變,則稱這種排序方法是不穩(wěn)定的。

要注意的是,排序算法的穩(wěn)定性是針對所有輸入實例而言的。即在所有可能的輸入實例中,只要有一個實例使得算法不滿足穩(wěn)定性要求,則該排序算法就是不穩(wěn)定的。

一.插入排序

插入排序的基本思想是每步將一個待排序的記錄按其排序碼值的大小,插到前面已經(jīng)排好的文件中的適當位置,直到全部插入完為止。插入排序方法主要有直接插入排序和希爾排序。

①.直接插入排序(穩(wěn)定)接插入排序的過程為:在插入第i個記錄時,R1,R2,..Ri-1已經(jīng)排好序,將第i個記錄的排序碼Ki依次和R1,R2,..,Ri-1的排序碼逐個進行比較,找到適當?shù)奈恢谩J褂弥苯硬迦肱判颍瑢τ诰哂衝個記錄的文件,要進行n-1趟排序。

代碼如下:

void Dir_Insert(int A[],int N)//直接插入排序 { int j,t;for(int i=1;it){ A[j+1]=A[j];j--;} A[j+1]=t;} } ②.希爾排序(不穩(wěn)定):

希爾(Shell)排序的基本思想是:先取一個小于n的整數(shù)d1作為第一個增量把文件的全部記錄分成d1個組。所有距離為d1的倍數(shù)的記錄放在同一個組中。先在各組內(nèi)進行直接插入排序;然后,取得第二個增量d2

一般取d1=n/2,di+1=di/2。如果結(jié)果為偶數(shù),則加1,保證di為奇數(shù)。

希爾排序是不穩(wěn)定的,希爾排序的執(zhí)行時間依賴于增量序列,其平均時間復(fù)雜度為O(n^1.3).代碼如下:

void Shell(int A[],int n)//Shell排序 { int i,j,k,t;(n/2)%2 == 0 ? k = n/2+1 : k = n/2;//保證增量為奇數(shù)

while(k > 0){ for(j=k;j=0 && A[i]>t){ A[i+k]=A[i];i=i-k;} A[i+k]=t;} if(k == 1)break;(k/2)%2 ==0 ? k=k/2+1 : k=k/2;} }

二.選擇排序

選擇排序的基本思想是每步從待排序的記錄中選出排序碼最小的記錄,順序存放在已排序的記錄序列的后面,直到全部排完。選擇排序中主要使用直接選擇排序和堆排 序。

①.直接選擇排序(不穩(wěn)定)

直接選擇排序的過程是:首先在所有記錄中選出序碼最小的記錄,把它與第1個記錄交換,然后在其余的記錄內(nèi)選出排序碼最小的記錄,與第2個記錄交換......依次類推,直到所有記錄排完為止。

無論文件初始狀態(tài)如何,在第i趟排序中選出最小關(guān)鍵字的記錄,需要做n-i次比較,因此,總的比較次數(shù)為n(n-1)/2=O(n^2)。當初始文件為正序時,移動次數(shù)為0;文件初態(tài)為反序時,每趟排序均要執(zhí)行交換操作,總的移動次數(shù)取最大值3(n-1)。直接選擇排序的平均時間復(fù)雜度為O(n^2)。直接選擇排序是不穩(wěn)定的。

代碼如下:

void Dir_Choose(int A[],int n)//直接選擇排序 { int k,t;for(int i=0;i

②.堆排序(不穩(wěn)定)

堆排序是一種樹形選擇排序,是對直接選擇排序的有效改進。n個關(guān)鍵字序列 K1,K2,...,Kn稱為堆,當且僅當該序列滿足(Ki<=K2i且Ki<=K2i+1)或(Ki>=K2i且Ki>=K2i+1),(1<=i<=n/2)。根結(jié)點(堆頂)的關(guān)鍵字是堆里所有結(jié)點關(guān)鍵字中最小者,稱為小根堆;根結(jié)點的關(guān)鍵字是堆里所有結(jié)點關(guān)鍵字中最大者,稱為大根堆。若將此序列所存儲的向量R[1..n]看作是一棵完全二叉樹的存儲結(jié)構(gòu),則堆實質(zhì)上是滿足如下性質(zhì)的完全二叉樹:樹中任一非葉結(jié)點的關(guān)鍵字均不大于(或不小于)其左右孩子(若存在)結(jié)點的關(guān)鍵字。

堆排序的關(guān)鍵步驟有兩個:一是如何建立初始堆;二是當堆的根結(jié)點與堆的最后一個結(jié)點交換后,如何對少了一個結(jié)點后的結(jié)點序列做調(diào)整,使之重新成為堆。堆排序的最壞時間復(fù)雜度為O(nlog2n),堆排序的平均性能較接近于最壞性能。由于建初始堆所需的比較 次數(shù)較多,所以堆排序不適宜于記錄較少的文件。堆排序是就地排序,輔助空間為O(1),它是不穩(wěn)定的排序方法。

代碼略..三.交換排序

交換排序的基本思想是:兩兩比較待排序記錄的排序碼,并交換不滿足順序要求的那寫偶對,直到滿足條件為止。交換排序的主要方法有冒泡排序和快速排序.①.冒泡排序(穩(wěn)定的)

冒泡排序?qū)⒈慌判虻挠涗洈?shù)組R[1..n]垂直排列,每個記錄R[i]看作是重量為ki的氣泡。根據(jù)輕氣泡不能在重氣泡之下的原則,從下往上掃描數(shù)組R;凡掃描到違反本原則的輕氣泡,就使其向上“漂浮”。如此反復(fù)進行,直到最后任何兩個氣泡都是輕者在上,重者在下為止。

冒泡排序的具體過程如下:

第一步,先比較k1和k2,若k1>k2,則交換k1和k2所在的記錄,否則不交換。繼續(xù)對k2和k3重復(fù)上述過程,直到處理完kn-1和kn。這時最大的排序碼記錄轉(zhuǎn)到了最后位置,稱第1次起泡,共執(zhí)行n-1次比較。

與第一步類似,從k1和k2開始比較,到kn-2和kn-1為止,共執(zhí)行n-2次比較。

依次類推,共做n-1次起泡,完成整個排序過程。

若文件的初始狀態(tài)是正序的,一趟掃描即可完成排序。所需關(guān)鍵字比較次數(shù)為n-1次,記錄移動次數(shù)為0。因此,冒泡排序最好的時間復(fù)雜度為O(n)。

若初始文件是反序的,需要進行n-1趟排序。每趟排序要進行n-i次關(guān)鍵字的比較(1<=i<=n-1),且每次比較都必須移動記錄三次來達到交換記錄位置。在這種情況下,比較次數(shù)達到最大值n(n-1)/2=O(n^2),移動次數(shù)也達到最大值3n(n-1)/2=O(n^2)。因此,冒泡排序的最壞時間復(fù)雜度為O(n^2)。

雖然冒泡排序不一定要進行n-1趟,但由于它的記錄移動次數(shù)較多,故平均性能比直接插入排序要差得多。冒泡排序是就地排序,且它是穩(wěn)定的。

代碼如下: void QP(int A[],int n)//優(yōu)化的冒泡排序

{ int count=0,t,flag;for(int i=0;i

②.快速排序:(不穩(wěn)定的)

快速排序采用了一種分治的策略,通常稱其為分治法,其基本思想是:將原問題分解為若干個規(guī)模更小但結(jié)構(gòu)與原問題相似的子問題。遞歸地解這些子問題,然后將這些子問題的解組合為原問題的解。

快速排序的具體過程如下:

第一步,在待排序的n個記錄中任取一個記錄,以該記錄的排序碼為準,將所有記錄分成兩組,第1組各記錄的排序碼都小于等于該排序碼,第2組各記錄的排序碼都大于該排序碼,并把該記錄排在這兩組中間。

第二步,采用同樣的方法,對左邊的組和右邊的組進行排序,直到所有記錄都排到相應(yīng)的位置為止。

代碼如下:

void Quick_Sort(int A[],int low,int high)//low和high是數(shù)組的下標 { if(low=t)h--;if(h>l){ temp=A[l];A[l]=A[h];A[h]=temp;} } Quick_Sort(A,low,l-1);Quick_Sort(A,l+1,high);} }

四.歸并排序

歸并排序是將兩個或兩個以上的有序子表合并成一個新的有序表。初始時,把含有n個結(jié)點的待排序序列看作由n個長度都為1的有序子表組成,將它們依次兩兩歸并得到長度為2的若干有序子表,再對它們兩兩合并。直到得到長度為n的有序表,排序結(jié)束。

歸并排序是一種穩(wěn)定的排序,可用順序存儲結(jié)構(gòu),也易于在鏈表上實現(xiàn),對長度為n的文件,需進行l(wèi)og2n趟二路歸并,每趟歸并的時間為O(n),故其時間復(fù)雜度無論是在最好情況下還是在最壞情況下均是O(nlog2n)。歸并排序需要一個輔助向量來暫存兩個有序子文件歸并的結(jié)果,故其輔助空間復(fù)雜度為O(n),顯然它不是就地排序。

代碼略...五.基數(shù)排序

設(shè)單關(guān)鍵字的每個分量的取值范圍均是C0<=Kj<=Crd-1(0<=j<=rd),可能的取值個數(shù)rd稱為基數(shù).基數(shù)的選擇和關(guān)鍵字的分解因關(guān)鍵字的類型而異.

(1).若關(guān)鍵字是十進制整數(shù),則按個、十等位進行分解,基數(shù)rd=10,C0=0,C9=9,d為最長整數(shù)的位數(shù).

(2).若關(guān)鍵字是小寫的英文字符串,則rd=26,C0='a',C25='z',d為最長字符串的長度.

基數(shù)排序的基本思想是:從低位到高位依次對待排序的關(guān)鍵碼進行分配和收集,經(jīng)過d趟分配和收集,就可以得到一個有序序列.

按平均時間將排序分為四類:

(1)平方階(O(n2))排序

一般稱為簡單排序,例如直接插入、直接選擇和冒泡排序;

(2)線性對數(shù)階(O(nlgn))排序

如快速、堆和歸并排序;

(3)O(n1+£)階排序

£是介于0和1之間的常數(shù),即0<£<1,如希爾排序;

(4)線性階(O(n))排序

如基數(shù)排序。

各種排序方法比較

簡單排序中直接插入最好,快速排序最快,當文件為正序時,直接插入和冒泡均最佳。

影響排序效果的因素

因為不同的排序方法適應(yīng)不同的應(yīng)用環(huán)境和要求,所以選擇合適的排序方法應(yīng)綜合考慮下列因素:

①待排序的記錄數(shù)目n;

②記錄的大小(規(guī)模);

③關(guān)鍵字的結(jié)構(gòu)及其初始狀態(tài);

④對穩(wěn)定性的要求;

⑤語言工具的條件;

⑥存儲結(jié)構(gòu);

⑦時間和輔助空間復(fù)雜度等。

不同條件下,排序方法的選擇

(1)若n較小(如n≤50),可采用直接插入或直接選擇排序。

當記錄規(guī)模較小時,直接插入排序較好;否則因為直接選擇移動的記錄數(shù)少于直接插人,應(yīng)選直接選擇排序為宜。

(2)若文件初始狀態(tài)基本有序(指正序),則應(yīng)選用直接插人、冒泡或隨機的快速排序為宜;(3)若n較大,則應(yīng)采用時間復(fù)雜度為O(nlgn)的排序方法:快速排序、堆排序或 歸并排序。

快速排序是目前基于比較的內(nèi)部排序中被認為是最好的方法,當待排序的關(guān)鍵字是隨機分布時,快速排序的平均時間最短;

堆排序所需的輔助空間少于快速排序,并且不會出現(xiàn)快速排序可能出現(xiàn)的最壞情況。這兩種排序都是不穩(wěn)定的。

若要求排序穩(wěn)定,則可選用歸并排序。但從單個記錄起進行兩兩歸并的 排序算法并不值得提倡,通常可以將它和直接插入排序結(jié)合在一起使用。先利用直接插入排序求得較長的有序子文件,然后再兩兩歸并之。因為直接插入排序是穩(wěn)定的,所以改進后的歸并排序仍是穩(wěn)定的。

第四篇:51CTO下載-排序和算法總結(jié)

事先聲明,此文檔來自某技術(shù)論壇,內(nèi)容歸原作者所有。

1.基本思想:

每一趟從待排序的數(shù)據(jù)元素中選出最小(或最大)的一個元素,順序放在已排好序的數(shù)列的最后,直到全部待排序的數(shù)據(jù)元素排完。2.排序過程: 【示例】:

初始關(guān)鍵字 [49 38 65 97 76 13 27 49] 第一趟排序后 13 [38 65 97 76 49 27 49] 第二趟排序后 13 27 [65 97 76 49 38 49] 第三趟排序后 13 27 38 [97 76 49 65 49] 第四趟排序后 13 27 38 49 [49 97 65 76] 第五趟排序后 13 27 38 49 49 [97 97 76] 第六趟排序后 13 27 38 49 49 76 [76 97] 第七趟排序后 13 27 38 49 49 76 76 [ 97] 最后排序結(jié)果 13 27 38 49 49 76 76 97 3.void selectionSort(Type* arr,long len){ long i=0,j=0;/*iterator value*/ long maxPos;assertF(arr!=NULL,“In InsertSort sort,arr is NULLn”);for(i=len-1;i>=1;i--){ maxPos=i;for(j=0;j

插入排序(Insertion Sort)的基本思想是:每次將一個待排序的記錄,按其關(guān)鍵字大小插入到前面已經(jīng)排好序的子文件中的適當位置,直到全部記錄插入完成為止。直接插入排序

直接插入排序(Straight Insertion Sort):將一個記錄插入到排好序的有序表中,從而得到一個新的、記錄數(shù)增1的有序表。直接插入排序算法

哨兵(監(jiān)視哨)有兩個作用:一是作為臨變量存放R[i](當前要進行比較的關(guān)鍵字)的副本;二是在查找循環(huán)中用來監(jiān)視下標變量j是否越界。

當文件的初始狀態(tài)不同時,直接插入排序所耗費的時間是有很大差異的。最好情況是文件初態(tài)為正序,此時算法的時間復(fù)雜度為O(n),最壞情況是文件初態(tài)為反序,相應(yīng)的時間復(fù)雜度為O(n2),算法的平均時間復(fù)雜度是O(n2)。算法的輔助空間復(fù)雜度是O(1),是一個就地排序。

直接插入排序是穩(wěn)定的排序方法。三.冒泡排序

[算法思想]:將被排序的記錄數(shù)組R[1..n]垂直排列,每個記錄R[i]看作是重量為R[i].key的氣泡。根據(jù)輕氣泡不能在重氣泡之下的原則,從下往上掃描數(shù)組R:凡掃描到違反本原則的輕氣泡,就使其向上“飄浮”。如此反

復(fù)進行,直到最后任何兩個氣泡都是輕者在上,重者在下為止。

[算法]:

void BubbleSort(SeqList R){ //R(l..n)是待排序的文件,采用自下向上掃描,對R做冒泡排序 int i,j;

Boolean exchange; //交換標志

for(i=1;i

exchange=FALSE; //本趟排序開始前,交換標志應(yīng)為假

for(j=n-1;j>=i;j--)//對當前無序區(qū)R[i..n]自下向上掃描 if(R[j+1].key

R[0]=R[j+1]; //R[0]不是哨兵,僅做暫存單元 R[j+1]=R[j]; R[j]=R[0];

exchange=TRUE; //發(fā)生了交換,故將交換標志置為真 } if(!exchange)return;//本趟排序未發(fā)生交換,提前終止算法 } //endfor(外循環(huán))} //BubbleSort [分析]:起泡排序的結(jié)束條件為:最后一趟沒有進行“交換”。從起泡排序的過程可見,起泡排序是一個增加有序序列長度的過程,也是一個縮小無序序列長度的過程,每經(jīng)過一趟起泡,無序序列的長度只縮小1。[算法思想]:將被排序的記錄數(shù)組R[1..n]垂直排列,每個記錄R[i]看作是重量為R[i].key的氣泡。根據(jù)輕氣泡不能在重氣泡之下的原則,從下往上掃描數(shù)組R:凡掃描到違反本原則的輕氣泡,就使其向上“飄浮”。如此反復(fù)進行,直到最后任何兩個氣泡都是輕者在上,重者在下為止。

[算法]:

void BubbleSort(SeqList R){ //R(l..n)是待排序的文件,采用自下向上掃描,對R做冒泡排序 int i,j;

Boolean exchange; //交換標志

for(i=1;i

exchange=FALSE; //本趟排序開始前,交換標志應(yīng)為假

for(j=n-1;j>=i;j--)//對當前無序區(qū)R[i..n]自下向上掃描 if(R[j+1].key

R[0]=R[j+1]; //R[0]不是哨兵,僅做暫存單元 R[j+1]=R[j]; R[j]=R[0];

exchange=TRUE; //發(fā)生了交換,故將交換標志置為真 } if(!exchange)return;//本趟排序未發(fā)生交換,提前終止算法 } //endfor(外循環(huán))} //BubbleSort [分析]:起泡排序的結(jié)束條件為:最后一趟沒有進行“交換”。從起泡排序的過程可見,起泡排序是一個增加有序序列長度的過程,也是一個縮小無序序列長度的過程,每經(jīng)過一趟起泡,無序序列的長度只縮小1。四.希爾排序 基本思想:

先取一個小于n的整數(shù)d1作為第一個增量,把文件的全部記錄分成d1個組。所有距離為d

l的倍數(shù)的記錄放在同一個組中。先在各組內(nèi)進行直接插人排序;然后,取第二個增量d2

該方法實質(zhì)上是一種分組插入方法。給定實例的shell排序的排序過程

假設(shè)待排序文件有10個記錄,其關(guān)鍵字分別是: 49,38,65,97,76,13,27,49,55,04。

增量序列的取值依次為: 5,3,1 Shell排序的算法實現(xiàn)

1. 不設(shè)監(jiān)視哨的算法描述

void ShellPass(SeqList R,int d){//希爾排序中的一趟排序,d為當前增量 for(i=d+1;i<=n;i++)//將R[d+1..n]分別插入各組當前的有序區(qū) if(R[i].key

R[j+d];=R[j]; //后移記錄 j=j-d; //查找前一記錄

}while(j>0&&R[0].key

R[j+d]=R[0]; //插入R[i]到正確的位置上 } //endif } //ShellPass void ShellSort(SeqList R){ int increment=n; //增量初值,不妨設(shè)n>0 do { increment=increment/3+1; //求下一增量

ShellPass(R,increment); //一趟增量為increment的Shell插入排序 }while(increment>1)} //ShellSort 注意:

當增量d=1時,ShellPass和InsertSort基本一致,只是由于沒有哨兵而在內(nèi)循環(huán)中增加了一個循環(huán)判定條件“j>0”,以防下標越界。2.設(shè)監(jiān)視哨的shell排序算法 算法分析

1.增量序列的選擇

Shell排序的執(zhí)行時間依賴于增量序列。

好的增量序列的共同特征:

① 最后一個增量必須為1;

② 應(yīng)該盡量避免序列中的值(尤其是相鄰的值)互為倍數(shù)的情況。

有人通過大量的實驗,給出了目前較好的結(jié)果:當n較大時,比較和移動的次數(shù)約在nl.25到1.6n1.25之間。

2.Shell排序的時間性能優(yōu)于直接插入排序

希爾排序的時間性能優(yōu)于直接插入排序的原因:

①當文件初態(tài)基本有序時直接插入排序所需的比較和移動次數(shù)均較少。

②當n值較小時,n和n2的差別也較小,即直接插入排序的最好時間復(fù)雜度O(n)和最壞時間復(fù)雜度0(n2)差別不大。

③在希爾排序開始時增量較大,分組較多,每組的記錄數(shù)目少,故各組內(nèi)直接插入較快,后來增量di逐漸縮小,分組數(shù)逐漸減少,而各組的記錄數(shù)目逐漸增多,但由于已經(jīng)按di-1作為距離排過序,使文件較接近于有序狀態(tài),所以新的一趟排序過程也較快。

因此,希爾排序在效率上較直接插人排序有較大的改進。3.穩(wěn)定性 希爾

排序是不穩(wěn)定的。參見上述實例,該例中兩個相同關(guān)鍵字49在排序前后的相對次序發(fā)生了變化。五.堆排序

1、堆排序定義

n個關(guān)鍵字序列Kl,K2,?,Kn稱為堆,當且僅當該序列滿足如下性質(zhì)(簡稱為堆性質(zhì)):

(1)ki≤K2i且ki≤K2i+1 或(2)Ki≥K2i且ki≥K2i+1(1≤i≤)

若將此序列所存儲的向量R[1..n]看做是一棵完全二叉樹的存儲結(jié)構(gòu),則堆實質(zhì)上是滿足如下性質(zhì)的完全二叉樹:樹中任一非葉結(jié)點的關(guān)鍵字均不大于(或不小于)其左右孩子(若存在)結(jié)點的關(guān)鍵字。

【例】關(guān)鍵字序列(10,15,56,25,30,70)和(70,56,30,25,15,10)分別滿足堆性質(zhì)(1)和(2),故它們均是堆,其對應(yīng)的完全二叉樹分別如小根堆示例和大根堆示例所示。

2、大根堆和小根堆

根結(jié)點(亦稱為堆頂)的關(guān)鍵字是堆里所有結(jié)點關(guān)鍵字中最小者的堆稱為小根堆。

根結(jié)點(亦稱為堆頂)的關(guān)鍵字是堆里所有結(jié)點關(guān)鍵字中最大者,稱為大根堆。注意:

①堆中任一子樹亦是堆。

②以上討論的堆實際上是二叉堆(Binary Heap),類似地可定義k叉堆。

3、堆排序特點

堆排序(HeapSort)是一樹形選擇排序。

堆排序的特點是:在排序過程中,將R[l..n]看成是一棵完全二叉樹的順序存儲結(jié)構(gòu),利用完全二叉樹中雙親結(jié)點和孩子結(jié)點之間的內(nèi)在關(guān)系【參見二叉樹的順序存儲結(jié)構(gòu)】,在當前無序區(qū)中選擇關(guān)鍵字最大(或最小)的記錄。

4、堆排序與直接插入排序的區(qū)別

直接選擇排序中,為了從R[1..n]中選出關(guān)鍵字最小的記錄,必須進行n-1次比較,然后在R[2..n]中選出關(guān)鍵字最小的記錄,又需要做n-2次比較。事實上,后面的n-2次比較中,有許多比較可能在前面的n-1次比較中已經(jīng)做過,但由于前一趟排序時未保留這些比較結(jié)果,所以后一趟排序時又重復(fù)執(zhí)行了這些比較操作。

堆排序可通過樹形結(jié)構(gòu)保存部分比較結(jié)果,可減少比較次數(shù)。

5、堆排序

堆排序利用了大根堆(或小根堆)堆頂記錄的關(guān)鍵字最大(或最小)這一特征,使得在當前無序區(qū)中選取最大(或最小)關(guān)鍵字的記錄變得簡單。(1)用大根堆排序的基本思想

① 先將初始文件R[1..n]建成一個大根堆,此堆為初始的無序區(qū)

② 再將關(guān)鍵字最大的記錄R[1](即堆頂)和無序區(qū)的最后一個記錄R[n]交換,由此得到新的無序區(qū)R[1..n-1]和有序區(qū)R[n],且滿足R[1..n-1].keys≤R[n].key ③ 由于交換后新的根R[1]可能違反堆性質(zhì),故應(yīng)將當前無序區(qū)R[1..n-1]調(diào)整為堆。然后再次將R[1..n-1]中關(guān)鍵字最大的記錄R[1]和該區(qū)間的最后一個記錄R[n-1]交換,由此得到新的無序區(qū)R[1..n-2]和有

序區(qū)R[n-1..n],且仍滿足關(guān)系R[1..n-2].keys≤R[n-1..n].keys,同樣要將R[1..n-2]調(diào)整為堆。

??

直到無序區(qū)只有一個元素為止。(2)大根堆排序算法的基本操作: ① 初始化操作:將R[1..n]構(gòu)造為初始堆;

② 每一趟排序的基本操作:將當前無序區(qū)的堆頂記錄R[1]和該區(qū)間的最后一個記錄交換,然后將新的無序區(qū)調(diào)整為堆(亦稱重建堆)。注意:

①只需做n-1趟排序,選出較大的n-1個關(guān)鍵字即可以使得文件遞增有序。

②用小根堆排序與利用大根堆類似,只不過其排序結(jié)果是遞減有序的。堆排序和直接選擇排序相反:在任何時刻,堆排序中無序區(qū)總是在有序區(qū)之前,且有序區(qū)是在原向量的尾部由后往前逐步擴大至整個向量為止。(3)堆排序的算法:

void HeapSort(SeqIAst R){ //對R[1..n]進行堆排序,不妨用R[0]做暫存單元 int i;

BuildHeap(R); //將R[1-n]建成初始堆

for(i=n;i>1;i--){ //對當前無序區(qū)R[1..i]進行堆排序,共做n-1趟。R[0]=R[1];R[1]=R[i];R[i]=R[0]; //將堆頂和堆中最后一個記錄交換

Heapify(R,1,i-1); //將R[1..i-1]重新調(diào)整為堆,僅有R[1]可能違反堆性質(zhì) } //endfor } //HeapSort(4)BuildHeap和Heapify函數(shù)的實現(xiàn)

因為構(gòu)造初始堆必須使用到調(diào)整堆的操作,先討論Heapify的實現(xiàn)。① Heapify函數(shù)思想方法

每趟排序開始前R[l..i]是以R[1]為根的堆,在R[1]與R[i]交換后,新的無序區(qū)R[1..i-1]中只有R[1]的值發(fā)生了變化,故除R[1]可能違反堆性質(zhì)外,其余任何結(jié)點為根的子樹均是堆。因此,當被調(diào)整區(qū)間是R[low..high]時,只須調(diào)整以R[low]為根的樹即可。“篩選法”調(diào)整堆

R[low]的左、右子樹(若存在)均已是堆,這兩棵子樹的根R[2low]和R[2low+1]分別是各自子樹中關(guān)鍵字最大的結(jié)點。若R[low].key不小于這兩個孩子結(jié)點的關(guān)鍵字,則R[low]未違反堆性質(zhì),以R[low]為根的樹已是堆,無須調(diào)整;否則必須將R[low]和它的兩個孩子結(jié)點中關(guān)鍵字較大者進行交換,即R[low]與R[large](R[large].key=max(R[2low].key,R[2low+1].key))交換。交換后又可能使結(jié)點R[large]違反堆性質(zhì),同樣由于該結(jié)點的兩棵子樹(若存在)仍然是堆,故可重復(fù)上述的調(diào)整過程,對以R[large]為根的樹進行調(diào)整。此過程直至當前被調(diào)整的結(jié)點已滿足堆性質(zhì),或者該結(jié)點已是葉子為止。上述過程就象過篩子一樣,把較小的關(guān)鍵字逐層篩下去,而將較大的關(guān)鍵字逐層選上來。因此,有人將此方法稱為“篩選法”。

②BuildHeap的實現(xiàn)

要將初始文件R[l..n]調(diào)整為一個大根堆,就必須將它所對應(yīng)的完全二叉樹中以每一結(jié)點為根的子樹都調(diào)整為堆。

顯然只有一個結(jié)點的 樹是堆,而在完全二叉樹中,所有序號 的結(jié)點都是葉子,因此以這些結(jié)點為根的子樹均已是堆。這樣,我們只需依次將以序號為,-1,?,1的結(jié)點作為根的子樹都調(diào)整為堆即可。

具體算法【參見教材】。

5、大根堆排序?qū)嵗?/p>

對于關(guān)鍵字序列(42,13,24,91,23,16,05,88),在建堆過程中完全二叉樹及其存儲結(jié)構(gòu)的變化情況參見。

6、算法分析

堆排序的時間,主要由建立初始堆和反復(fù)重建堆這兩部分的時間開銷構(gòu)成,它們均是通過調(diào)用Heapify實現(xiàn)的。

堆排序的最壞時間復(fù)雜度為O(nlgn)。堆排序的平均性能較接近于最壞性能。

由于建初始堆所需的比較次數(shù)較多,所以堆排序不適宜于記錄數(shù)較少的文件。

堆排序是就地排序,輔助空間為O(1),它是不穩(wěn)定的排序方法。六.快速排序

快速排序的基本思路是:首先我們選擇一個中間值middle(程序中我們可使用數(shù)組中間值),把比中間值小的放在其左邊,比中間值大的放在其右邊。由于這個排序算法較復(fù)雜,我們先給出其進行一次排序的程序框架(從各類數(shù)據(jù)結(jié)構(gòu)教材中可得): void QuickSort(int *pData, int left, int right){ int i, j;int middle, iTemp;i = left;j = right;middle = pData[(left + right)/ 2];//求中間值

do {

while((pData[i] < middle)&&(i < right))//從左掃描大于中值的數(shù)

i++;

while((pData[j] > middle)&&(j > left))//從右掃描小于中值的數(shù)

j--;

if(i <= j)//找到了一對值

{

//交換

iTemp = pData[i];

pData[i] = pData[j];

pData[j] = iTemp;

i++;

j--;

} } while(i <= j);//如果兩邊掃描的下標交錯,就停止(完成一次)

//當左邊部分有值(left

if(left

QuickSort(pData,left,j);

//當右邊部分有值(right>i),遞歸右半邊

if(right>i)

QuickSort(pData,i,right);} 對于n個成員,快速排序法的比較次數(shù)大約為n*logn 次,交換次數(shù)大約為(n*logn)/6次。如果n為100,冒泡法需要進行4950 次比較,而快速排序法僅需要200 次,快速排序法的效率的確很高。快速排序法的性能與中間值的選定關(guān)系密切,如果每一次選擇的中間值都是最大值(或最小值),該算法的速度就會大大下降。快速排序算法最壞情況下的時間復(fù)雜度為O(n2),而平均時間復(fù)雜度為O(n*logn)。七.合并排序 說明

之前所介紹的排序法都是在同一個陣列中的排序,考慮今日有兩筆或兩筆以上的資料,它可能是不同陣列中的資料,或是不同檔案中的資料,如何為它們進行排序? 解法

可以使用合併排序法,合併排序法基本是將兩筆已排序的資料合併並進行排序,如果所讀入的資料尚未排序,可以先利用其它的排序方式來處理這兩筆資料,然後再將排序好的這兩筆資料合併。

有人問道,如果兩筆資料本身就無排序順序,何不將所有的資料讀入,再一次進行排序?排序的精神是儘量利用資料已排序的部份,來加快排序的效率,小筆資料的排序較為快速,如果小筆資料排序完成之後,再合併處理時,因為兩筆資料都有排序了,所有在合併排序時會比單純讀入所有的資料再一次排序來的有效率。那麼可不可以直接使用合併排序法本身來處理整個排序的動作?而不動用到其它的排序方式?答案是肯定的,只要將所有的數(shù)字不斷的分為兩個等分,直到最後剩一個數(shù)字為止,然後再反過來不斷的合併,就如下圖所示:

不過基本上分割又會花去額外的時間,不如使用其它較好的排序法來排序小筆資料,再使用合併排序來的有效率。

下面這個程式範例,我們使用快速排序法來處理小筆資料排序,然後再使用合併排序法處理合併的動作。例子

C

#include #include #include #define MAX1 10 #define MAX2 10 #define SWAP(x,y){int t;t = x;x = y;y = t;} int partition(int[], int, int);void quicksort(int[], int, int);void mergesort(int[], int, int[], int, int[]);int main(void){ int number1[MAX1] = {0};int number2[MAX1] = {0};int number3[MAX1+MAX2] = {0};int i, num;srand(time(NULL));printf(“排序前:”);printf(“nnumber1[]:”);for(i = 0;i < MAX1;i++){ number1[i] = rand()% 100;printf(“%d ”, number1[i]);} printf(“nnumber2[]:”);for(i = 0;i < MAX2;i++){ number2[i] = rand()% 100;printf(“%d ”, number2[i]);} // 先排序兩筆資料

quicksort(number1, 0, MAX1-1);quicksort(number2, 0, MAX2-1);printf(“n排序後:”);printf(“nnumber1[]:”);for(i = 0;i < MAX1;i++)printf(“%d ”, number1[i]);printf(“nnumber2[]:”);for(i = 0;i < MAX2;i++)printf(“%d ”, number2[i]);// 合併排序

mergesort(number1, MAX1, number2, MAX2, number3);printf(“n合併後:”);for(i = 0;i < MAX1+MAX2;i++)printf(“%d ”, number3[i]);printf(“n”);return 0;} int partition(int number[], int left, int right){ int i, j, s;s = number[right];i = left-1;for(j = left;j < right;j++){ if(number[j] <= s){ i++;SWAP(number[i], number[j]);} } SWAP(number[i+1], number[right]);return i+1;} void quicksort(int number[], int left, int right){ int q;if(left < right){ q = partition(number, left, right);quicksort(number, left, q-1);quicksort(number, q+1, right);} } void mergesort(int number1[], int M, int number2[], int N, int number3[]){ int i

=

0, j = 0, k = 0;while(i < M && j < N){ if(number1[i] <= number2[j])number3[k++] = number1[i++];else number3[k++] = number2[j++];} while(i < M)number3[k++] = number1[i++];while(j < N)number3[k++] = number2[j++];} Java

public class MergeSort { public static int[] sort(int[] number1, int[] number2){ int[] number3 = new int[number1.length + number2.length];int i = 0, j = 0, k = 0;while(i < number1.length && j < number2.length){ if(number1[i] <= number2[j])number3[k++] = number1[i++];else number3[k++] = number2[j++];} while(i < number1.length)number3[k++] = number1[i++];while(j < number2.length)number3[k++] = number2[j++];return number3;} } 八。基數(shù)排序

基數(shù)排序是根據(jù)組成關(guān)鍵字的各位值,用“分配”和“收集”的方法進行排序。例如,把撲克牌的排序看成由花色和面值兩個數(shù)據(jù)項組成的主關(guān)鍵字排序。

花色:梅花<方塊<紅心<黑桃

面值:2<3<4<...<10

若要將一副撲克牌排成下列次序:

梅花2,...,梅花A,方塊2,...,方塊A,紅心2,...,紅心A,黑桃2,...,黑桃A。

有兩種排序方法:

一、先按花色分成四堆,把各堆收集起來;然后對每堆按面值由小到大排列,再按花色從小到大按堆收疊起來。----稱為“最高位優(yōu)先”(MSD)法。

二、先按面值由小到大排列成13堆,然后從小到大收集起來;再按花色不同分成四堆,最后順序收集起來。----稱為“最低位優(yōu)先”(LSD)法。

[例] 設(shè)記錄鍵值序列為{88,71,60,31,87,35,56,18},用基數(shù)排序(LSD)。如圖所示:其中f[i]、e[i]為按位分配面值為i的隊列的隊頭和隊尾指針。

#define D 3 typedef struct { int key;float data;int link;} JD

key data link int jspx(JD r[],int n){ /*鏈式存儲表示的基數(shù)排序*/ int i,j,k,t,p,rd,rg,f[10],e[10];/*p為r[]的下標,rd,rg為比例因子,f[j],e[j]是代碼為j的隊的首尾指針*/ for(i=1;i0);j=0;/*按位收集--調(diào)整分配后的鏈接*/ while(f[j]==0)j=j+1;p=f[j];t=e[j];for(k=j+1;k<10;k++)if(f[k]>0){ r[t].link=f[k];t=e[k];}/*調(diào)整鏈接*/ r[t].link=0;/*鏈尾為0*/ rg=rg*10;rd=rd*10;/*提高一位*/ } return(p);/*返回有序鏈表的首地址*/ 九 枚舉排序

將每個記錄項與其他諸項比較計算出小于該項的記錄個數(shù),以確定該項的位置。

第五篇:10種排序算法總結(jié)

10種排序算法總結(jié)

排序算法有很多,所以在特定情景中使用哪一種算法很重要。為了選擇合適的算法,可以按照建議的順序考慮以下標準:(1)執(zhí)行時間(2)存儲空間(3)編程工作

對于數(shù)據(jù)量較小的情形,(1)(2)差別不大,主要考慮(3);而對于數(shù)據(jù)量大的,(1)為首要。主要排序法有:

一、冒泡(Bubble)排序——相鄰交換

二、選擇排序——每次最小/大排在相應(yīng)的位置

三、插入排序——將下一個插入已排好的序列中

四、殼(Shell)排序——縮小增量

五、歸并排序

六、快速排序

七、堆排序

八、拓撲排序

九、錦標賽排序

十、基數(shù)排序

一、冒泡(Bubble)排序

---Code 從小到大排序n個數(shù)-----voidBubbleSortArray(){ for(int i=1;ia[j+1])//比較交換相鄰元素 { int temp;temp=a[j];a[j]=a[j+1];a[j+1]=temp;} } } }------------------Code-----------------效率 O(n2),適用于排序小列表。

二、選擇排序

---Code 從小到大排序n個數(shù)-voidSelectSortArray(){ intmin_index;for(int i=0;i

三、插入排序

-------------Code 從小到大排序n個數(shù)------voidInsertSortArray(){ for(int i=1;i=0 &&arr[j]>temp)/*將temp與已排序元素從小到大比較,尋找temp應(yīng)插入的位置*/ { arr[j+1]=arr[j];j--;} arr[j+1]=temp;} }------------------------------Code 最佳效率O(n);最糟效率O(n2)與冒泡、選擇相同,適用于排序小列表 若列表基本有序,則插入排序比冒泡、選擇更有效率。

四、殼(Shell)排序——縮小增量排序

------Code 從小到大排序n個數(shù)------voidShellSortArray(){ for(intincr=3;incr<0;incr--)//增量遞減,以增量3,2,1為例 { for(int L=0;L<(n-1)/incr;L++)//重復(fù)分成的每個子列表 { for(int i=L+incr;i=0&&arr[j]>temp){ arr[j+incr]=arr[j];j-=incr;} arr[j+incr]=temp;} } } }-------Code------------適用于排序小列表。

效率估計O(nlog2^n)~O(n^1.5),取決于增量值的最初大小。建議使用質(zhì)數(shù)作為增量值,因為如果增量值是2的冪,則在下一個通道中會再次比較相同的元素。

殼(Shell)排序改進了插入排序,減少了比較的次數(shù)。是不穩(wěn)定的排序,因為排序過程中元素可能會前后跳躍。

五、歸并排序

---------------Code 從小到大排序--------voidMergeSort(intlow,int high){ if(low>=high)return;//每個子列表中剩下一個元素時停止

else int mid=(low+high)/2;/*將列表劃分成相等的兩個子列表,若有奇數(shù)個元素,則在左邊子列表大于右側(cè)子列表*/ MergeSort(low,mid);//子列表進一步劃分 MergeSort(mid+1,high);int [] B=new int [high-low+1];//新建一個數(shù)組,用于存放歸并的元素

for(int i=low,j=mid+1,k=low;i<=mid && j<=high;k++)/*兩個子列表進行排序歸并,直到兩個子列表中的一個結(jié)束*/ { if(arr[i]<=arr[j];){ B[k]=arr[i];I++;} else { B[k]=arr[j];j++;} } for(;j<=high;j++,k++)//如果第二個子列表中仍然有元素,則追加到新列表 B[k]=arr[j];for(;i<=mid;i++,k++)//如果在第一個子列表中仍然有元素,則追加到新列表中 B[k]=arr[i];for(int z=0;z

六、快速排序

-----Code-------------/*快速排序的算法思想:選定一個樞紐元素,對待排序序列進行分割,分割之后的序列一個部分小于樞紐元素,一個部分大于樞紐元素,再對這兩個分割好的子序列進行上述的過程。*/ void swap(inta,int b){intt;t =a;a =b;b =t;} int Partition(int [] arr,intlow,int high){ int pivot=arr[low];//采用子序列的第一個元素作為樞紐元素 while(low < high){ //從后往前栽后半部分中尋找第一個小于樞紐元素的元素 while(low < high &&arr[high] >= pivot){--high;} //將這個比樞紐元素小的元素交換到前半部分 swap(arr[low], arr[high]);//從前往后在前半部分中尋找第一個大于樞紐元素的元素 while(low

此算法的總時間取決于樞紐值的位置;選擇第一個元素作為樞紐,可能導(dǎo)致O(n2)的最糟用例效率。若數(shù)基本有序,效率反而最差。選項中間值作為樞紐,效率是O(nlogn)。基于分治法。

七、堆排序

最大堆:后者任一非終端節(jié)點的關(guān)鍵字均大于或等于它的左、右孩子的關(guān)鍵字,此時位于堆頂?shù)墓?jié)點的關(guān)鍵字是整個序列中最大的。思想:

(1)令i=l,并令temp= kl;(2)計算i的左孩子j=2i+1;(3)若j<=n-1,則轉(zhuǎn)(4),否則轉(zhuǎn)(6);(4)比較kj和kj+1,若kj+1>kj,則令j=j(luò)+1,否則j不變;

(5)比較temp和kj,若kj>temp,則令ki等于kj,并令i=j,j=2i+1,并轉(zhuǎn)(3),否則轉(zhuǎn)(6)(6)令ki等于temp,結(jié)束。

----------Code---------------------------void HeapSort(SeqIAst R){ //對R[1..n]進行堆排序,不妨用R[0]做暫存單元 int I;BuildHeap(R); //將R[1-n]建成初始堆for(i=n;i>1;i--)//對當前無序區(qū)R[1..i]進行堆排序,共做n-1趟。{ R[0]=R[1];R[1]=R[i];R[i]=R[0];//將堆頂和堆中最后一個記錄交換 Heapify(R,1,i-1);//將R[1..i-1]重新調(diào)整為堆,僅有R[1]可能違反堆性質(zhì) } }--------Code-------

堆排序的時間,主要由建立初始堆和反復(fù)重建堆這兩部分的時間開銷構(gòu)成,它們均是通過調(diào)用Heapify實現(xiàn)的。

堆排序的最壞時間復(fù)雜度為O(nlgn)。堆排序的平均性能較接近于最壞性能。由于建初始堆所需的比較次數(shù)較多,所以堆排序不適宜于記錄數(shù)較少的文件。堆排序是就地排序,輔助空間為O(1),它是不穩(wěn)定的排序方法。

堆排序與直接插入排序的區(qū)別: 直接選擇排序中,為了從R[1..n]中選出關(guān)鍵字最小的記錄,必須進行n-1次比較,然后在R[2..n]中選出關(guān)鍵字最小的記錄,又需要做n-2次比較。事實上,后面的n-2次比較中,有許多比較可能在前面的n-1次比較中已經(jīng)做過,但由于前一趟排序時未保留這些比較結(jié)果,所以后一趟排序時又重復(fù)執(zhí)行了這些比較操作。

堆排序可通過樹形結(jié)構(gòu)保存部分比較結(jié)果,可減少比較次數(shù)。

八、拓撲排序

例 :學(xué)生選修課排課先后順序

拓撲排序:把有向圖中各頂點按照它們相互之間的優(yōu)先關(guān)系排列成一個線性序列的過程。方法:

在有向圖中選一個沒有前驅(qū)的頂點且輸出 從圖中刪除該頂點和所有以它為尾的弧

重復(fù)上述兩步,直至全部頂點均已輸出(拓撲排序成功),或者當圖中不存在無前驅(qū)的頂點(圖中有回路)為止。

--------Code-------void TopologicalSort()/*輸出拓撲排序函數(shù)。若G無回路,則輸出G的頂點的一個拓撲序列并返回OK,否則返回ERROR*/ { intindegree[M];inti,k,j;char n;int count=0;Stack thestack;FindInDegree(G,indegree);//對各頂點求入度indegree[0....num] InitStack(thestack);//初始化棧 for(i=0;i

九、錦標賽排序

錦標賽排序的算法思想與體育比賽類似。

首先將n個數(shù)據(jù)元素兩兩分組,分別按關(guān)鍵字進行比較,得到n/2個比較的優(yōu)勝者(關(guān)鍵字小者),作為第一步比較的結(jié)果保留下來,然后對這n/2個數(shù)據(jù)元素再兩兩分組,分別按關(guān)鍵字進行比較,?,如此重復(fù),直到選出一個關(guān)鍵字最小的數(shù)據(jù)元素為止。

-Code in C--------#include #include #include #include #define SIZE 100000 #define MAX 1000000 struct node { long num;//關(guān)鍵字 char str[10];intlastwin;//最后勝的對手 int killer;//被擊敗的對手 long times;//比賽次數(shù) }data[SIZE];long CompareNum=0;long ExchangeNum=0;long Read(char name[])//讀取文件a.txt中的數(shù)據(jù),并存放在數(shù)組data[]中;最后返回數(shù)據(jù)的個數(shù) { FILE *fp;long i=1;fp=fopen(name,“rw”);fscanf(fp,“%d%s”,&data[i].num,data[i].str);while(!feof(fp)){ i++;fscanf(fp,“%d%s”,&data[i].num,data[i].str);} return(i-1);} long Create(long num)//創(chuàng)建勝者樹,返回冠軍(最小數(shù))在數(shù)組data[]中的下標 { int i,j1,j2,max,time=1;long min;//記錄當前冠軍的下標 for(i=1;pow(2,i-1)num)data[i].num=MAX;} for(i=1;i<=max;i+=2)//第一輪比賽 { ++CompareNum;if(data[i].num<= data[i+1].num){ data[i].lastwin = i+1;data[i+1].killer=i;++data[i].times;++data[i+1].times;min=i;} else { data[i+1].lastwin=i;data[i].killer=i+1;++data[i].times;++data[i+1].times;min=i+1;} } j1=j2=0;//記錄連續(xù)的兩個未被淘汰的選手的下標 while(time <=(log(max)/log(2)))//進行淘汰賽 { for(i=1;i<=max;i++){ if(data[i].times==time && data[i].killer==0)//找到一名選手 { j2=i;//默認其為兩選手中的后來的

if(j1==0)//如果第一位置是空的,則剛來的選手先來的 j1=j2;else//否則剛來的選手是后來的,那么選手都已到場比賽開始 { ++CompareNum;if(data[j1].num<= data[j2].num)//先來的選手獲勝 { data[j1].lastwin = j2;//最后贏的是j2 data[j2].killer=j1;//j2是被j1淘汰的 ++data[j1].times;++data[j2].times;//兩選手場次均加1 min=j1;//最小數(shù)下標為j1 j1=j2=0;//將j1,j2置0 } else//同理 { data[j2].lastwin=j1;data[j1].killer=j2;++data[j1].times;++data[j2].times;min=j2;j1=j2=0;} } } } time++;//輪數(shù)加1 } return min;//返回冠軍的下標 } void TournamentSort(long num)//錦標賽排序 { long tag=Create(num);//返回最小數(shù)下標 FILE *fp1;fp1=fopen(“sort.txt”,“w+”);//為寫入創(chuàng)建并打開文件sort.txt while(data[tag].num!= MAX)//當最小值不是無窮大時 { printf(“%d %sn”,data[tag].num,data[tag].str);//輸出數(shù)據(jù) fprintf(fp1,“%d %sn”,data[tag].num,data[tag].str);//寫入數(shù)據(jù) data[tag].num=MAX;//將當前冠軍用無窮大替換 tag=Create(num);//返回下一個冠軍的下標 } } int main(){ intnum;char name[10];printf(“Input name of the file:”);gets(name);num=Read(name);//讀文件

TournamentSort(num);//錦標賽排序

printf(“CompareNum=%dnExchangeNum=%dn”,CompareNum,ExchangeNum);return 0;}-----------Code------

十、基數(shù)排序

基數(shù)排序又被稱為桶排序。與前面介紹的幾種排序方法相比較,基數(shù)排序和它們有明顯的不同。

前面所介紹的排序方法都是建立在對數(shù)據(jù)元素關(guān)鍵字進行比較的基礎(chǔ)上,所以可以稱為基于比較的排序; 而基數(shù)排序首先將待排序數(shù)據(jù)元素依次“分配”到不同的桶里,然后再把各桶中的數(shù)據(jù)元素“收集”到一起。

通過使用對多關(guān)鍵字進行排序的這種“分配”和“收集”的方法,基數(shù)排序?qū)崿F(xiàn)了對多關(guān)鍵字進行排序。——————————————————————————————————————— 例:

每張撲克牌有兩個“關(guān)鍵字”:花色和面值。其大小順序為: 花色:§<¨<?<a 面值:2<3<??<K<A 撲克牌的大小先根據(jù)花色比較,花色大的牌比花色小的牌大;花色一樣的牌再根據(jù)面值比較大小。所以,將撲克牌按從小到大的次序排列,可得到以下序列: §2,?,§A,¨2,?,¨A,?2,?,?A,a2,?,aA 這種排序相當于有兩個關(guān)鍵字的排序,一般有兩種方法實現(xiàn)。

其一:可以先按花色分成四堆(每一堆牌具有相同的花色),然后在每一堆牌里再按面值從小到大的次序排序,最后把已排好序的四堆牌按花色從小到大次序疊放在一起就得到排序的結(jié)果。其二:可以先按面值排序分成十三堆(每一堆牌具有相同的面值),然后將這十三堆牌按面值從小到大的順序疊放在一起,再把整副牌按順序根據(jù)花色再分成四堆(每一堆牌已按面值從小到大的順序有序),最后將這四堆牌按花色從小到大合在一起就得到排序的結(jié)果。

——————————————————————————————————————— 實現(xiàn)方法:

最高位優(yōu)先(Most Significant Digit first)法,簡稱MSD法:先按k1排序分組,同一組中記錄,關(guān)鍵碼k1相等,再對各組按k2排序分成子組,之后,對后面的關(guān)鍵碼繼續(xù)這樣的排序分組,直到按最次位關(guān)鍵碼kd對各子組排序后。再將各組連接起來,便得到一個有序序列。

最低位優(yōu)先(Least Significant Digit first)法,簡稱LSD法:先從kd開始排序,再對kd-1進行排序,依次重復(fù),直到對k1排序后便得到一個有序序列。

--Code in C#-----------

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace LearnSort

{

class Program

{

static void Main(string[] args)

{

int[] arr = CreateRandomArray(10);//產(chǎn)生隨機數(shù)組

Print(arr);//輸出數(shù)組

RadixSort(ref arr);//排序

Print(arr);//輸出排序后的結(jié)果

Console.ReadKey();

}

public static void RadixSort(ref int[] arr)

{

intiMaxLength = GetMaxLength(arr);

RadixSort(ref arr, iMaxLength);

}

private static void RadixSort(ref int[] arr, intiMaxLength)

{

List list = new List();//存放每次排序后的元素

List[] listArr = new List[10];//十個桶

char currnetChar;//存放當前的字符比如說某個元素123 中的2

string currentItem;//存放當前的元素比如說某個元素123

for(int i = 0;i

listArr[i] = new List();

for(int i = 0;i

{

foreach(int number in arr)//分桶

{

currentItem = number.ToString();//將當前元素轉(zhuǎn)化成字符串

try { currnetChar = currentItem[currentItem.Length-i-1];}//從個位向高位開始分桶

catch { listArr[0].Add(number);continue;}//如果發(fā)生異常,則將該數(shù)壓入listArr[0]。比如說5 是沒有十位數(shù)的,執(zhí)行上面的操作肯定會發(fā)生越界異常的,這正是期望的行為,我們認為5的十位數(shù)是0,所以將它壓入listArr[0]的桶里。

switch(currnetChar)//通過currnetChar的值,確定它壓人哪個桶中。

{

case '0': listArr[0].Add(number);break;

case '1': listArr[1].Add(number);break;

case '2': listArr[2].Add(number);break;

case '3': listArr[3].Add(number);break;

case '4': listArr[4].Add(number);break;

case '5': listArr[5].Add(number);break;

case '6': listArr[6].Add(number);break;

case '7': listArr[7].Add(number);break;

case '8': listArr[8].Add(number);break;

case '9': listArr[9].Add(number);break;

default: throw new Exception(“unknow error”);

}

}

for(int j = 0;j

foreach(int number in listArr[j].ToArray())

{

list.Add(number);

listArr[j].Clear();//清空每個桶

}

arr = list.ToArray();//arr指向重新排列的元素

//Console.Write(“{0} times:”,i);

Print(arr);//輸出一次排列的結(jié)果

list.Clear();//清空list

}

}

//得到最大元素的位數(shù)

private static intGetMaxLength(int[] arr)

{

intiMaxNumber = Int32.MinValue;

foreach(int i in arr)//遍歷得到最大值

{

if(i >iMaxNumber)

iMaxNumber = i;

}

return iMaxNumber.ToString().Length;//這樣獲得最大元素的位數(shù)是不是有點投機取巧了...}

//輸出數(shù)組元素

public static void Print(int[] arr)

{

foreach(int i in arr)

System.Console.Write(i.ToString()+'t');

System.Console.WriteLine();

}

//產(chǎn)生隨機數(shù)組。隨機數(shù)的范圍是0到1000。參數(shù)iLength指產(chǎn)生多少個隨機數(shù)

public static int[] CreateRandomArray(intiLength)

{

int[] arr = new int[iLength];

Random random = new Random();

for(int i = 0;i

arr[i] = random.Next(0,1001);

return arr;

}

}

}--Code--------------基數(shù)排序法是屬于穩(wěn)定性的排序,其時間復(fù)雜度為O(nlog(r)m),其中r為所采取的基數(shù),而m為堆數(shù),在某些時候,基數(shù)排序法的效率高于其它的比較性排序法。

下載用php實現(xiàn)的各種排序算法總結(jié)word格式文檔
下載用php實現(xiàn)的各種排序算法總結(jié).doc
將本文檔下載到自己電腦,方便修改和收藏,請勿使用迅雷等下載。
點此處下載文檔

文檔為doc格式


聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻自行上傳,本網(wǎng)站不擁有所有權(quán),未作人工編輯處理,也不承擔(dān)相關(guān)法律責(zé)任。如果您發(fā)現(xiàn)有涉嫌版權(quán)的內(nèi)容,歡迎發(fā)送郵件至:645879355@qq.com 進行舉報,并提供相關(guān)證據(jù),工作人員會在5個工作日內(nèi)聯(lián)系你,一經(jīng)查實,本站將立刻刪除涉嫌侵權(quán)內(nèi)容。

相關(guān)范文推薦

    《算法導(dǎo)論》學(xué)習(xí)總結(jié)——快速排序

    《算法導(dǎo)論》學(xué)習(xí)總結(jié)——快速排序 曾經(jīng)在程序員雜志上看到快速排序的作者,Hoare,曾經(jīng)的圖靈獎獲得者啊,牛光閃閃的。不過當時,對快速排序什么的,印象不算深刻,畢竟沒好好學(xué)。記......

    各種排序算法的優(yōu)缺點

    一、冒泡排序 已知一組無序數(shù)據(jù)a[1]、a[2]、……a[n],需將其按升序排列。首先比較a[1]與 a[2]的值,若a[1]大于a[2]則交換兩者的值,否則不變。再比較a[2]與a[3]的值,若a[2]大于a[......

    排序算法教學(xué)反思

    《選擇排序》教學(xué)心得 教學(xué)內(nèi)容: 選擇排序的算法思想 選擇排序的實現(xiàn)過程 選擇排序的編碼實現(xiàn) 總結(jié)和思考:大數(shù)據(jù)背景下的排序 排序(Sort) 是計算機程序設(shè)計中的一種重要操作......

    php頁面緩存實現(xiàn)方法總結(jié)范文

    php頁面緩存實現(xiàn)方法總結(jié) 在php頁面緩存主要用到的是ob系列函數(shù),如ob_start(),ob_end_flush(),ob_get_contents(),但是更高級的緩存是不使用這些函數(shù)的,本文章最后一個實現(xiàn)就......

    操作系統(tǒng)課程設(shè)計實驗報告-用C++實現(xiàn)銀行家算法

    操 作 系 統(tǒng) 實 驗 報 告 (2) 學(xué)院:計算機科學(xué)與技術(shù)學(xué)院 班級:計091 學(xué)號:姓名: 時間:2011/12/30 目 錄 1. 實驗名稱……………………………………………………3 2. 實驗?zāi)康摹?.....

    4.4排序算法設(shè)計5篇

    排序算法設(shè)計 一、內(nèi)容分析 【教學(xué)目標】 1、理解排序的概念 2、了解常用排序方法 3、理解冒泡排序的基本思路 4、應(yīng)用冒泡排序法進行排序 【重點難點】 1、冒泡排序法的基......

    算法設(shè)計與實現(xiàn)個人課程總結(jié)

    算法課程總結(jié) 指導(dǎo)教師 所在院(系) 班 級 學(xué)生姓名 學(xué) 號 一、算法概述 1.什么是算法? 算法是解一確定類問題的任意一種特殊的方法。在計算機科學(xué)中,算法是使用計算機解一類問......

    PHP 程序員學(xué)數(shù)據(jù)結(jié)構(gòu)與算法之《棧》

    PHP 程序員學(xué)數(shù)據(jù)結(jié)構(gòu)與算法之《棧》 介紹 “要成高手,必練此功”。 要成為優(yōu)秀的程序員,數(shù)據(jù)結(jié)構(gòu)和算法是必修的內(nèi)容。而現(xiàn)在的Web程序員使用傳統(tǒng)算法和數(shù)據(jù)結(jié)構(gòu)都比較少,因為......

主站蜘蛛池模板: 少妇无码太爽了不卡视频在线看| 无码熟妇人妻av在线电影| 国产亚洲午夜高清国产拍精品| 国产精品一卡二卡三卡四卡| 国产福利一区二区三区高清| 熟女人妻aⅴ一区二区三区麻豆| 欧美伦费免费全部午夜最新| 99久久免费看少妇高潮a片特黄| 无翼乌工口肉肉无遮挡无码18| 亚洲一区二区三区在线观看精品中文| 国产成人av无码精品天堂| 久久66热人妻偷产精品9| 亚洲色大成网站www久久| 久久久无码人妻精品一区| 永久在线观看免费视频| 国产在线精品一区二区三区| 精品伊人久久大线蕉色首页| 久久精品一区二区免费播放| 国产午夜无码片在线观看影院| 国产精品被窝福利一区| 久久和欧洲码一码二码三码| 亚洲一本大道av久在线播放| 视频一区二区无码制服师生| 色哟哟最新在线观看入口| 亚洲熟女乱色一区二区三区| 少妇被躁爽到高潮无码文| 午夜不卡无码中文字幕影院| 日日躁夜夜躁狠狠躁超碰97| 国产成人综合日韩精品无码不卡| 亚洲aⅴ男人的天堂在线观看| 一本色道久久综合无码人妻| 亚洲精品无码成人av电影网| 77色午夜成人影院综合网| 狠狠色狠狠色综合久久| 国产欧美va欧美va在线| 亚洲字幕av一区二区三区四区| 国产成人av在线影院无毒| 欧美成人精品一区二区综合a片| 欧美人与性动交ccoo| 十八岁以下禁止观看黄下载链接| 国产精品无码翘臀在线看|