冒泡排序改進演算法
Ⅰ 求一個插入排序和冒泡排序的改進演算法
This is C++ code.
插入排序:
bool insertionsort(int *array,int n)
{
int temp; //用來存儲,插入的數據
for(int i=1;i<n;i++)
{
temp=array[i]; //用temp記錄array[i]
for(int j=i-1;j>=0;j--) //逐個向前尋找插入點
{
if(temp>array[j]) //找到,跳出循環
break;
else //沒找到,將前一個數據後移
array[j+1]=array[j];
}
array[j+1]=temp;
}
return true;
}
復制代碼思想: 逐個取數,插入一個有序數組(從後向前插)
演算法平均時間復雜度: O(n^2)
冒泡排序:
bool bottomupsort(int *array,int n)
{
int length=1,temp_length,i; //temp_length表示單個合並數組的長度
while(length<n)
{
temp_length=length; //length表示合並後數組的長度
length=2*temp_length;
i=0; //i用於記錄合並數組的起始位置
while(i+length-1<=n-1)
{
merge(array,i,i+temp_length,i+length-1); //合並i~i+temp_length-1 和 i+temp_length~i+length-1 段
i=i+length; //取下一個合並段的起始位置
}
if(i+temp_length<n-1)
merge(array,i,i+temp_length,n-1); //對尾部剩餘段合並
}
return true;
}
bool merge(int *array,int start1,int start2,int n) //合並兩個有序數組
{
int temp_n=n-start1+1, //兩合並數組的長度和
*temp_array,
n1=start2-1, //第一個有序數組的末端位置
temp_start1=start1; //記錄start1的初始位置
temp_array=(int *)malloc(sizeof(int)*temp_n); //申請長度為temp_n的整形空間,用於臨時存儲合並後的數組
for(int i=0;start1<=n1&&start2<=n;i++) //對兩個有序數組進行合並,存儲於temp_array
{
if(array[start1]<=array[start2])
{
temp_array[i]=array[start1];
start1++;
}
else
{
temp_array[i]=array[start2];
start2++;
}
}
if(start1<=n1)
{
while(start1<=n1)
{
temp_array[i++]=array[start1];
start1++;
}
}
else
{
while(start2<=n)
{
temp_array[i++]=array[start2];
start2++;
}
}
for(i=0,start1=temp_start1;i<temp_n;start1++,i++) //將合並後的有序數組,復制到array數組中
{
array[start1]=temp_array[i];
}
free(temp_array);
return true;
}
演算法平均時間復雜度: O(nlogn)
Ⅱ 數據結構 編寫冒泡排序演算法函數,把一個有n個浮點數的數組,按升序排序
================================================
功能:冒泡排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
================================================
*/
/*
====================================================
演算法思想簡單描述:
在要排序的一組數中,對當前還未排好序的范圍內的全部數,自上
而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較
小的往上冒。即:每當兩相鄰的數比較後發現它們的排序與排序要
求相反時,就將它們互換。
下面是一種改進的冒泡演算法,它記錄了每一遍掃描後最後下沉數的
位置k,這樣可以減少外層循環掃描的次數。
冒泡排序是穩定的。演算法時間復雜度O(n2)--[n的平方]
=====================================================
*/
void bubble_sort(int x[], int n)
{
int j, k, h, t;
for (h=n-1; h>0; h=k) /*循環到沒有比較范圍*/
{
for (j=0, k=0; j<h; j++) /*每次預置k=0,循環掃描後更新k*/
{
if (*(x+j) > *(x+j+1)) /*大的放在後面,小的放到前面*/
{
t = *(x+j);
*(x+j) = *(x+j+1);
*(x+j+1) = t; /*完成交換*/
k = j; /*保存最後下沉的位置。這樣k後面的都是排序排好了的。*/
}
}
}
} 對的
Ⅲ c語言作業,急。。。。
第一個問題:(有點多,慢慢看哦~~)
main()
{
int i,j,temp;
int a[10];
for(i=0;i<10;i++)
scanf ("%d,",&a[i]);
for(j=0;j<=9;j++)
{ for (i=0;i<10-j;i++)
if (a[i]>a[i+1])
{ temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;}
}
for(i=1;i<11;i++)
printf("%5d,",a[i] );
printf("\n");
}
--------------
冒泡演算法
冒泡排序的演算法分析與改進
交換排序的基本思想是:兩兩比較待排序記錄的關鍵字,發現兩個記錄的次序相反時即進行交換,直到沒有反序的記錄為止。
應用交換排序基本思想的主要排序方法有:冒泡排序和快速排序。
冒泡排序
1、排序方法
將被排序的記錄數組R[1..n]垂直排列,每個記錄R看作是重量為R.key的氣泡。根據輕氣泡不能在重氣泡之下的原則,從下往上掃描數組R:凡掃描到違反本原則的輕氣泡,就使其向上"飄浮"。如此反復進行,直到最後任何兩個氣泡都是輕者在上,重者在下為止。
(1)初始
R[1..n]為無序區。
(2)第一趟掃描
從無序區底部向上依次比較相鄰的兩個氣泡的重量,若發現輕者在下、重者在上,則交換二者的位置。即依次比較(R[n],R[n-1]),(R[n-1],R[n-2]),…,(R[2],R[1]);對於每對氣泡(R[j+1],R[j]),若R[j+1].key<R[j].key,則交換R[j+1]和R[j]的內容。
第一趟掃描完畢時,"最輕"的氣泡就飄浮到該區間的頂部,即關鍵字最小的記錄被放在最高位置R[1]上。
(3)第二趟掃描
掃描R[2..n]。掃描完畢時,"次輕"的氣泡飄浮到R[2]的位置上……
最後,經過n-1 趟掃描可得到有序區R[1..n]
注意:
第i趟掃描時,R[1..i-1]和R[i..n]分別為當前的有序區和無序區。掃描仍是從無序區底部向上直至該區頂部。掃描完畢時,該區中最輕氣泡飄浮到頂部位置R上,結果是R[1..i]變為新的有序區。
2、冒泡排序過程示例
對關鍵字序列為49 38 65 97 76 13 27 49的文件進行冒泡排序的過程
3、排序演算法
(1)分析
因為每一趟排序都使有序區增加了一個氣泡,在經過n-1趟排序之後,有序區中就有n-1個氣泡,而無序區中氣泡的重量總是大於等於有序區中氣泡的重量,所以整個冒泡排序過程至多需要進行n-1趟排序。
若在某一趟排序中未發現氣泡位置的交換,則說明待排序的無序區中所有氣泡均滿足輕者在上,重者在下的原則,因此,冒泡排序過程可在此趟排序後終止。為此,在下面給出的演算法中,引入一個布爾量exchange,在每趟排序開始前,先將其置為FALSE。若排序過程中發生了交換,則將其置為TRUE。各趟排序結束時檢查exchange,若未曾發生過交換則終止演算法,不再進行下一趟排序。
(2)具體演算法
void BubbleSort(SeqList R)
{ //R(l..n)是待排序的文件,採用自下向上掃描,對R做冒泡排序
int i,j;
Boolean exchange; //交換標志
for(i=1;i<n;i++){ //最多做n-1趟排序
exchange=FALSE; //本趟排序開始前,交換標志應為假
for(j=n-1;j>=i;j--) //對當前無序區R[i..n]自下向上掃描
if(R[j+1].key<R[j].key){//交換記錄
R[0]=R[j+1]; //R[0]不是哨兵,僅做暫存單元
R[j+1]=R[j];
R[j]=R[0];
exchange=TRUE; //發生了交換,故將交換標志置為真
}
if(!exchange) //本趟排序未發生交換,提前終止演算法
return;
} //endfor(外循環)
} //BubbleSort
4、演算法分析
(1)演算法的最好時間復雜度
若文件的初始狀態是正序的,一趟掃描即可完成排序。所需的關鍵字比較次數C和記錄移動次數M均達到最小值:
Cmin=n-1
Mmin=0。
冒泡排序最好的時間復雜度為O(n)。
(2)演算法的最壞時間復雜度
若初始文件是反序的,需要進行n-1趟排序。每趟排序要進行n-i次關鍵字的比較(1≤i≤n-1),且每次比較都必須移動記錄三次來達到交換記錄位置。在這種情況下,比較和移動次數均達到最大值:
Cmax=n(n-1)/2=O(n2)
Mmax=3n(n-1)/2=O(n2)
冒泡排序的最壞時間復雜度為O(n2)。
(3)演算法的平均時間復雜度為O(n2)
雖然冒泡排序不一定要進行n-1趟,但由於它的記錄移動次數較多,故平均時間性能比直接插入排序要差得多。
(4)演算法穩定性
冒泡排序是就地排序,且它是穩定的。
5、演算法改進
上述的冒泡排序還可做如下的改進:
(1)記住最後一次交換發生位置lastExchange的冒泡排序
在每趟掃描中,記住最後一次交換發生的位置lastExchange,(該位置之前的相鄰記錄均已有序)。下一趟排序開始時,R[1..lastExchange-1]是有序區,R[lastExchange..n]是無序區。這樣,一趟排序可能使當前有序區擴充多個記錄,從而減少排序的趟數。具體演算法【參見習題】。
(2) 改變掃描方向的冒泡排序
①冒泡排序的不對稱性
能一趟掃描完成排序的情況:
只有最輕的氣泡位於R[n]的位置,其餘的氣泡均已排好序,那麼也只需一趟掃描就可以完成排序。
【例】對初始關鍵字序列12,18,42,44,45,67,94,10就僅需一趟掃描。
需要n-1趟掃描完成排序情況:
當只有最重的氣泡位於R[1]的位置,其餘的氣泡均已排好序時,則仍需做n-1趟掃描才能完成排序。
【例】對初始關鍵字序列:94,10,12,18,42,44,45,67就需七趟掃描。
②造成不對稱性的原因
每趟掃描僅能使最重氣泡"下沉"一個位置,因此使位於頂端的最重氣泡下沉到底部時,需做n-1趟掃描。
③改進不對稱性的方法
在排序過程中交替改變掃描方向,可改進不對稱性。
第二個問題:OK,我們可以直接套公式
(首項加末項)*項數/2
於是:就有了第一種方法:
#include<stdio.h>
void main()
{
int a=1,b=99,c100,d=0;
d=(a+b)*100/2;
printf("%d",d);
}
第二種方法:(普遍)
#include<stdio.h>
void main()
{
int shuzu[100]={1,2,3,4,5,6,7,我暈,如果非要用數組做的話,麻煩你慢慢打到一百o(∩_∩)o...,97,98,99,100};
int i,k=0;
for(i=0;i<100;i++)
k=shuzu[i]+k;
printf("%d",k);
}
OK希望能幫助您
Ⅳ C語言冒泡排序法
冒泡排序每一趟排序把最大的放在最右邊。
比如:
87 12 56 45 78
87和12交換:12 87 56 45 78
87和56交換: 56 87 45 78
87和45交換: 45 87 78
87和78交換: 78 87
到此第一趟排序結束,接下來的每一趟排序都是這樣。
#include<stdio.h>
voidPrint(int*num,intn)
{
inti;
for(i=0;i<n;i++)
printf("%d",num[i]);
puts(" ");
return;
}
voidBubble_Sort(int*num,intn)
{
inti,j;
for(i=0;i<n;i++)
{
for(j=0;i+j<n-1;j++)
{
if(num[j]>num[j+1])
{
inttemp=num[j];
num[j]=num[j+1];
num[j+1]=temp;
}
Print(num,n);
}
}
return;
}
intmain()
{
intnum[8]={87,12,56,45,78};
Bubble_Sort(num,5);
return0;
}
Ⅳ 起泡法排序
1.起泡排序演算法的原理 起泡排序是交換排序的一種,其基本方法是:設待排序元素列中元素...
2.起泡排序的基本演算法
3.template<classT>
4.voidBubbleSort(T arr[],intn){
5.起泡排序的時間復雜度分析 起泡排序演算法中,第i趟起泡需要執行n-i次比較和交換操作。因此,i從1到n-1,執行的比較操作的次數為: (n-1)+(n-2)+ …...
Ⅵ 在C語言中,冒泡排序是怎樣做的如題 謝謝了
main() { int i,j,temp; int a[10]; for(i=0;i<10;i++) scanf ("%d,",&a[i]); for(j=0;j<=9;j++) { for (i=0;i<10-j;i++) if (a[i]>a[i+1]) { temp=a[i]; a[i]=a[i+1]; a[i+1]=temp;} } for(i=1;i<11;i++) printf("%5d,",a[i] ); printf("\n"); } -------------- 冒泡演算法 冒泡排序的演算法分析與改進 交換排序的基本思想是:兩兩比較待排序記錄的關鍵字,發現兩個記錄的次序相反時即進行交換,直到沒有反序的記錄為止。 應用交換排序基本思想的主要排序方法有:冒泡排序和快速排序。 冒泡排序 1、排序方法 將被排序的記錄數組R[1..n]垂直排列,每個記錄R看作是重量為R.key的氣泡。根據輕氣泡不能在重氣泡之下的原則,從下往上掃描數組R:凡掃描到違反本原則的輕氣泡,就使其向上"飄浮"。如此反復進行,直到最後任何兩個氣泡都是輕者在上,重者在下為止。 (1)初始 R[1..n]為無序區。 (2)第一趟掃描 從無序區底部向上依次比較相鄰的兩個氣泡的重量,若發現輕者在下、重者在上,則交換二者的位置。即依次比較(R[n],R[n-1]),(R[n-1],R[n-2]),…,(R[2],R[1]);對於每對氣泡(R[j+1],R[j]),若R[j+1].key<R[j].key,則交換R[j+1]和R[j]的內容。 第一趟掃描完畢時,"最輕"的氣泡就飄浮到該區間的頂部,即關鍵字最小的記錄被放在最高位置R[1]上。 (3)第二趟掃描 掃描R[2..n]。掃描完畢時,"次輕"的氣泡飄浮到R[2]的位置上…… 最後,經過n-1 趟掃描可得到有序區R[1..n] 注意: 第i趟掃描時,R[1..i-1]和R[i..n]分別為當前的有序區和無序區。掃描仍是從無序區底部向上直至該區頂部。掃描完畢時,該區中最輕氣泡飄浮到頂部位置R上,結果是R[1..i]變為新的有序區。 2、冒泡排序過程示例 對關鍵字序列為49 38 65 97 76 13 27 49的文件進行冒泡排序的過程 3、排序演算法 (1)分析 因為每一趟排序都使有序區增加了一個氣泡,在經過n-1趟排序之後,有序區中就有n-1個氣泡,而無序區中氣泡的重量總是大於等於有序區中氣泡的重量,所以整個冒泡排序過程至多需要進行n-1趟排序。 若在某一趟排序中未發現氣泡位置的交換,則說明待排序的無序區中所有氣泡均滿足輕者在上,重者在下的原則,因此,冒泡排序過程可在此趟排序後終止。為此,在下面給出的演算法中,引入一個布爾量exchange,在每趟排序開始前,先將其置為FALSE。若排序過程中發生了交換,則將其置為TRUE。各趟排序結束時檢查exchange,若未曾發生過交換則終止演算法,不再進行下一趟排序。 (2)具體演算法 void BubbleSort(SeqList R) { //R(l..n)是待排序的文件,採用自下向上掃描,對R做冒泡排序 int i,j; Boolean exchange; //交換標志 for(i=1;i<n;i++){ //最多做n-1趟排序 exchange=FALSE; //本趟排序開始前,交換標志應為假 for(j=n-1;j>=i;j--) //對當前無序區R[i..n]自下向上掃描 if(R[j+1].key<R[j].key){//交換記錄 R[0]=R[j+1]; //R[0]不是哨兵,僅做暫存單元 R[j+1]=R[j]; R[j]=R[0]; exchange=TRUE; //發生了交換,故將交換標志置為真 } if(!exchange) //本趟排序未發生交換,提前終止演算法 return; } //endfor(外循環) } //BubbleSort 4、演算法分析 (1)演算法的最好時間復雜度 若文件的初始狀態是正序的,一趟掃描即可完成排序。所需的關鍵字比較次數C和記錄移動次數M均達到最小值: Cmin=n-1 Mmin=0。 冒泡排序最好的時間復雜度為O(n)。 (2)演算法的最壞時間復雜度 若初始文件是反序的,需要進行n-1趟排序。每趟排序要進行n-i次關鍵字的比較(1≤i≤n-1),且每次比較都必須移動記錄三次來達到交換記錄位置。在這種情況下,比較和移動次數均達到最大值: Cmax=n(n-1)/2=O(n2) Mmax=3n(n-1)/2=O(n2) 冒泡排序的最壞時間復雜度為O(n2)。 (3)演算法的平均時間復雜度為O(n2) 雖然冒泡排序不一定要進行n-1趟,但由於它的記錄移動次數較多,故平均時間性能比直接插入排序要差得多。 (4)演算法穩定性 冒泡排序是就地排序,且它是穩定的。 5、演算法改進 上述的冒泡排序還可做如下的改進: (1)記住最後一次交換發生位置lastExchange的冒泡排序 在每趟掃描中,記住最後一次交換發生的位置lastExchange,(該位置之前的相鄰記錄均已有序)。下一趟排序開始時,R[1..lastExchange-1]是有序區,R[lastExchange..n]是無序區。這樣,一趟排序可能使當前有序區擴充多個記錄,從而減少排序的趟數。具體演算法【參見習題】。 (2) 改變掃描方向的冒泡排序 ①冒泡排序的不對稱性 能一趟掃描完成排序的情況: 只有最輕的氣泡位於R[n]的位置,其餘的氣泡均已排好序,那麼也只需一趟掃描就可以完成排序。 【例】對初始關鍵字序列12,18,42,44,45,67,94,10就僅需一趟掃描。 需要n-1趟掃描完成排序情況: 當只有最重的氣泡位於R[1]的位置,其餘的氣泡均已排好序時,則仍需做n-1趟掃描才能完成排序。 【例】對初始關鍵字序列:94,10,12,18,42,44,45,67就需七趟掃描。 ②造成不對稱性的原因 每趟掃描僅能使最重氣泡"下沉"一個位置,因此使位於頂端的最重氣泡下沉到底部時,需做n-1趟掃描。 ③改進不對稱性的方法 在排序過程中交替改變掃描方向,可改進不對稱性
Ⅶ c語言冒泡排序的編程
#include <stdio.h>
void sort(int *a,int len)
{int i=0;
int j;
int t;
for(i=0;i<len-1;i++)
{
for(j=0;j<len-i-1;j++)
{
if(a[j]>a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
}
int main(int argc, char *argv[])
{
int a[10]={
-999,2,3,77,12,88,0,-8,99,100
};
int i=0;
sort(a,10);
for(i=0;i<10;i++)
{
printf(%d ,a[i]);
}
return 0;
}
冒泡演算法冒泡排序的演算法分析與改進 交換排序的基本思想是:兩兩比較待排序記錄的關鍵字,發現兩個記錄的次序相反時即進行交換,直到沒有反序的記錄為止。 應用交換排序基本思想的主要排序方法有:冒泡排序和快速排序。
冒泡排序 1、排序方法 將被排序的記錄數組R[1..n]垂直排列,每個記錄R看作是重量為R.key的氣泡。根據輕氣泡不能在重氣泡之下的原則,從下往上掃描數組R:凡掃描到違反本原則的輕氣泡,就使其向上飄浮。如此反復進行,直到最後任何兩個氣泡都是輕者在上,重者在下為止。 (1)初始 R[1..n]為無序區。 (2)第一趟掃描 從無序區底部向上依次比較相鄰的兩個氣泡的重量,若發現輕者在下、重者在上,則交換二者的位置。即依次比較(R[n],R[n-1]),(R[n-1],R[n-2]),…,(R[2],R[1]);對於每對氣泡(R[j+1],R[j]),若R[j+1].key<R[j].key,則交換R[j+1]和R[j]的內容。 第一趟掃描完畢時,最輕的氣泡就飄浮到該區間的頂部,即關鍵字最小的記錄被放在最高位置R[1]上。 (3)第二趟掃描 掃描R[2..n]。掃描完畢時,次輕的氣泡飄浮到R[2]的位置上…… 最後,經過n-1 趟掃描可得到有序區R[1..n] 注意: 第i趟掃描時,R[1..i-1]和R[i..n]分別為當前的有序區和無序區。掃描仍是從無序區底部向上直至該區頂部。掃描完畢時,該區中最輕氣泡飄浮到頂部位置R上,結果是R[1..i]變為新的有序區。
2、冒泡排序過程示例 對關鍵字序列為49 38 65 97 76 13 27 49的文件進行冒泡排序的過程
3、排序演算法 (1)分析 因為每一趟排序都使有序區增加了一個氣泡,在經過n-1趟排序之後,有序區中就有n-1個氣泡,而無序區中氣泡的重量總是大於等於有序區中氣泡的重量,所以整個冒泡排序過程至多需要進行n-1趟排序。 若在某一趟排序中未發現氣泡位置的交換,則說明待排序的無序區中所有氣泡均滿足輕者在上,重者在下的原則,因此,冒泡排序過程可在此趟排序後終止。為此,在下面給出的演算法中,引入一個布爾量exchange,在每趟排序開始前,先將其置為FALSE。若排序過程中發生了交換,則將其置為TRUE。各趟排序結束時檢查exchange,若未曾發生過交換則終止演算法,不再進行下一趟排序。 (2)具體演算法 void BubbleSort(SeqList R) { //R(l..n)是待排序的文件,採用自下向上掃描,對R做冒泡排序 int i,j; Boolean exchange; //交換標志 for(i=1;i<n;i++){ //最多做n-1趟排序 exchange=FALSE; //本趟排序開始前,交換標志應為假 for(j=n-1;j>=i;j--) //對當前無序區R[i..n]自下向上掃描 if(R[j+1].key<R[j].key){//交換記錄 R[0]=R[j+1]; //R[0]不是哨兵,僅做暫存單元 R[j+1]=R[j]; R[j]=R[0]; exchange=TRUE; //發生了交換,故將交換標志置為真 } if(!exchange) //本趟排序未發生交換,提前終止演算法 return; } //endfor(外循環) } //BubbleSort
4、演算法分析 (1)演算法的最好時間復雜度 若文件的初始狀態是正序的,一趟掃描即可完成排序。所需的關鍵字比較次數C和記錄移動次數M均達到最小值: Cmin=n-1 Mmin=0。 冒泡排序最好的時間復雜度為O(n)。 (2)演算法的最壞時間復雜度 若初始文件是反序的,需要進行n-1趟排序。每趟排序要進行n-i次關鍵字的比較(1≤i≤n-1),且每次比較都必須移動記錄三次來達到交換記錄位置。在這種情況下,比較和移動次數均達到最大值: Cmax=n(n-1)/2=O(n2) Mmax=3n(n-1)/2=O(n2) 冒泡排序的最壞時間復雜度為O(n2)。 (3)演算法的平均時間復雜度為O(n2) 雖然冒泡排序不一定要進行n-1趟,但由於它的記錄移動次數較多,故平均時間性能比直接插入排序要差得多。 (4)演算法穩定性 冒泡排序是就地排序,且它是穩定的。 5、演算法改進 上述的冒泡排序還可做如下的改進: (1)記住最後一次交換發生位置lastExchange的冒泡排序 在每趟掃描中,記住最後一次交換發生的位置lastExchange,(該位置之前的相鄰記錄均已有序)。下一趟排序開始時,R[1..lastExchange-1]是有序區,R[lastExchange..n]是無序區。這樣,一趟排序可能使當前有序區擴充多個記錄,從而減少排序的趟數。具體演算法【參見習題】。 (2) 改變掃描方向的冒泡排序 ①冒泡排序的不對稱性 能一趟掃描完成排序的情況: 只有最輕的氣泡位於R[n]的位置,其餘的氣泡均已排好序,那麼也只需一趟掃描就可以完成排序。
【例】對初始關鍵字序列12,18,42,44,45,67,94,10就僅需一趟掃描。 需要n-1趟掃描完成排序情況: 當只有最重的氣泡位於R[1]的位置,其餘的氣泡均已排好序時,則仍需做n-1趟掃描才能完成排序。
【例】對初始關鍵字序列:94,10,12,18,42,44,45,67就需七趟掃描。 ②造成不對稱性的原因 每趟掃描僅能使最重氣泡下沉一個位置,因此使位於頂端的最重氣泡下沉到底部時,需做n-1趟掃描。 ③改進不對稱性的方法 在排序過程中交替改變掃描方向,可改進不對稱性。
Ⅷ 請編程實現一個冒泡排序演算法
演算法思想簡單描述:
在要排序的一組數中,對當前還未排好序的范圍內的全部數,自上
而下對相鄰的兩個數依次進行比較和調整,讓較大的數往下沉,較
小的往上冒。即:每當兩相鄰的數比較後發現它們的排序與排序要
求相反時,就將它們互換。
下面是一種改進的冒泡演算法,它記錄了每一遍掃描後最後下沉數的
位置k,這樣可以減少外層循環掃描的次數。
冒泡排序是穩定的。演算法時間復雜度O(n^2)
演算法實現:
/*
功能:冒泡排序
輸入:數組名稱(也就是數組首地址)、數組中元素個數
*/
void bubble_sort(int *x, int n)
{
int j, k, h, t;
for (h=n-1; h>0; h=k) /*循環到沒有比較范圍*/
{
for (j=0, k=0; j<h; j++) /*每次預置k=0,循環掃描後更新k*/
{
if (*(x+j) > *(x+j+1)) /*大的放在後面,小的放到前面*/
{
t = *(x+j);
*(x+j) = *(x+j+1);
*(x+j+1) = t; /*完成交換*/
k = j; /*保存最後下沉的位置。這樣k後面的都是排序排好了的。*/
}
}
}
}
Ⅸ C語言冒泡排序不太理解
C語言冒泡排序就是將被排序的記錄數組R[1..n]垂直排列,每個記錄R看作是重量為R.key的氣泡。根據輕氣泡不能在重氣泡之下的原則,從下往上掃描數組R:凡掃描到違反本原則的輕氣泡,就使其向上"飄浮"。如此反復進行,直到最後任何兩個氣泡都是輕者在上,重者在下為止。
冒泡演算法冒泡排序的演算法分析與改進 交換排序的基本思想是:
兩兩比較待排序記錄的關鍵字,發現兩個記錄的次序相反時即進行交換,直到沒有反序的記錄為止。 應用交換排序基本思想的主要排序方法有:冒泡排序和快速排序。
冒泡排序
1、排序方法 將被排序的記錄數組R[1..n]垂直排列,每個記錄R看作是重量為R.key的氣泡。根據輕氣泡不能在重氣泡之下的原則,從下往上掃描數組R:凡掃描到違反本原則的輕氣泡,就使其向上"飄浮"。如此反復進行,直到最後任何兩個氣泡都是輕者在上,重者在下為止。
(1)初始 R[1..n]為無序區。
(2)第一趟掃描 從無序區底部向上依次比較相鄰的兩個氣泡的重量,若發現輕者在下、重者在上,則交換二者的位置。即依次比較(R[n],R[n-1]),(R[n-1],R[n-2]),…,(R[2],R[1]);對於每對氣泡(R[j+1],R[j]),若R[j+1].key<R[j].key,則交換R[j+1]和R[j]的內容。 第一趟掃描完畢時,"最輕"的氣泡就飄浮到該區間的頂部,即關鍵字最小的記錄被放在最高位置R[1]上。
(3)第二趟掃描 掃描R[2..n]。掃描完畢時,"次輕"的氣泡飄浮到R[2]的位置上…… 最後,經過n-1 趟掃描可得到有序區R[1..n] 注意: 第i趟掃描時,R[1..i-1]和R[i..n]分別為當前的有序區和無序區。掃描仍是從無序區底部向上直至該區頂部。掃描完畢時,該區中最輕氣泡飄浮到頂部位置R上,結果是R[1..i]變為新的有序區。
2、冒泡排序過程示例 :
對關鍵字序列為49 38 65 97 76 13 27 49的文件進行冒泡排序的過程
3、排序演算法 :
(1)分析 因為每一趟排序都使有序區增加了一個氣泡,在經過n-1趟排序之後,有序區中就有n-1個氣泡,而無序區中氣泡的重量總是大於等於有序區中氣泡的重量,所以整個冒泡排序過程至多需要進行n-1趟排序。 若在某一趟排序中未發現氣泡位置的交換,則說明待排序的無序區中所有氣泡均滿足輕者在上,重者在下的原則,因此,冒泡排序過程可在此趟排序後終止。為此,在下面給出的演算法中,引入一個布爾量exchange,在每趟排序開始前,先將其置為FALSE。若排序過程中發生了交換,則將其置為TRUE。各趟排序結束時檢查exchange,若未曾發生過交換則終止演算法,不再進行下一趟排序。
(2)具體演算法 void BubbleSort(SeqList R) { //R(l..n)是待排序的文件,採用自下向上掃描,對R做冒泡排序 int i,j; Boolean exchange; //交換標志 for(i=1;i<n;i++){ //最多做n-1趟排序 exchange=FALSE; //本趟排序開始前,交換標志應為假 for(j=n-1;j>=i;j--) //對當前無序區R[i..n]自下向上掃描 if(R[j+1].key<R[j].key){//交換記錄 R[0]=R[j+1]; //R[0]不是哨兵,僅做暫存單元 R[j+1]=R[j]; R[j]=R[0]; exchange=TRUE; //發生了交換,故將交換標志置為真 } if(!exchange) //本趟排序未發生交換,提前終止演算法 return; } //endfor(外循環) } //BubbleSort
4、演算法分析 :
(1)演算法的最好時間復雜度 若文件的初始狀態是正序的,一趟掃描即可完成排序。所需的關鍵字比較次數C和記錄移動次數M均達到最小值: Cmin=n-1 Mmin=0。 冒泡排序最好的時間復雜度為O(n)。
(2)演算法的最壞時間復雜度 若初始文件是反序的,需要進行n-1趟排序。每趟排序要進行n-i次關鍵字的比較(1≤i≤n-1),且每次比較都必須移動記錄三次來達到交換記錄位置。在這種情況下,比較和移動次數均達到最大值: Cmax=n(n-1)/2=O(n2) Mmax=3n(n-1)/2=O(n2) 冒泡排序的最壞時間復雜度為O(n2)。
(3)演算法的平均時間復雜度為O(n2) 雖然冒泡排序不一定要進行n-1趟,但由於它的記錄移動次數較多,故平均時間性能比直接插入排序要差得多。
(4)演算法穩定性 冒泡排序是就地排序,且它是穩定的。
5、演算法改進 上述的冒泡排序還可做如下的改進:
(1)記住最後一次交換發生位置lastExchange的冒泡排序 在每趟掃描中,記住最後一次交換發生的位置lastExchange,(該位置之前的相鄰記錄均已有序)。下一趟排序開始時,R[1..lastExchange-1]是有序區,R[lastExchange..n]是無序區。這樣,一趟排序可能使當前有序區擴充多個記錄,從而減少排序的趟數。
(2) 改變掃描方向的冒泡排序,冒泡排序的不對稱性 能一趟掃描完成排序的情況: 只有最輕的氣泡位於R[n]的位置,其餘的氣泡均已排好序,那麼也只需一趟掃描就可以完成排序。
【例】對初始關鍵字序列12,18,42,44,45,67,94,10就僅需一趟掃描。 需要n-1趟掃描完成排序情況: 當只有最重的氣泡位於R[1]的位置,其餘的氣泡均已排好序時,則仍需做n-1趟掃描才能完成排序。
【例】對初始關鍵字序列:94,10,12,18,42,44,45,67就需七趟掃描。 ②造成不對稱性的原因 每趟掃描僅能使最重氣泡"下沉"一個位置,因此使位於頂端的最重氣泡下沉到底部時,需做n-1趟掃描。 ③改進不對稱性的方法 在排序過程中交替改變掃描方向,可改進不對稱性。
Ⅹ 請寫最簡單最易懂的冒泡排序【改進】演算法!怎麼寫!C++!
你這個代碼已經含了這種思想在裡面啊
只是沒有顯示地表達出來, 也就是沒有單獨用pos來作標記