當前位置:首頁 » 操作系統 » 排序改進演算法

排序改進演算法

發布時間: 2022-07-22 03:08:22

1. 選擇法排序和改進選擇法排序

//選擇排序法void SelectSort(int data[],int n){ int i,j,temp,min,pos,flag; for(i=0;i<n-1;i++)//掃描n-1次,由i=0,1,...,n-2 { //順序查找data[i]至data[n-1]之間的最小值及位置 min=data[i]; pos=i; flag=0;//假設data[i]為最小值 for(j=i+1;j<n;j++) { if(min>data[j]) { min=data[j]; pos=j; flag=1; } } if(flag==1)//如果最小值改變,則進行交換 { temp=data[i]; data[i]=data[pos]; data[pos]=temp; }
} cout<<"選擇排序後的數據為: "; Display(data,N);}
改進排序就是將待排序的第一個數據與為排序的最小的一個交換,這樣每趟就只需要交換一次;而沒有改進的話,可能要進行多次交換。

2. 對內排序演算法的改進及性能比較

public class XPX
{
public static void main(String args[])
{
int i,j,t,min;
int a[]={9,8,7,6,5,4,3,2,1};
for(i=0;i<8;i++)
{
min = a[i];
for(j=i;j<a.length;j++)
{
if(min>a[j])
{
min = a[j];
a[j]=a[i];
a[i]=min;
}
}
}
for(i=0;i<a.length;i++)
{
System.out.print(" "+a[i]);
}
System.out.println();
}
}

3. 排序有幾種方法

一. 冒泡排序

冒泡排序是是一種簡單的排序演算法。它重復地遍歷要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把它們交換過來。遍歷數列的工作是重復的進行直到沒有再需要交換,也就是說該數列已經排序完成。這個演算法的名字由來是因為越小的元素會經由交換慢慢「浮」到數列的頂端

1.冒泡排序演算法的運作如下:
(1)比較相鄰的元素。如果第一個比第二個大(升序),就交換他們兩個
(2)對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素還是最大的數
(3)針對所有的元素重復以上的步驟,除了最後一個
二. 選擇排序
選擇排序是一種簡單直觀的排序演算法。他的工作原理如下:
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置(末尾位置),然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。以此類推,直到所有元素均排序完畢
選擇排序的主要優點與數據移動有關。如果某個元素位於正確的最終位置上,則它不會被移動。選擇排序每次交換一對元素,他們當中至少有一個將被移到最終位置上,因此對n個元素的表進行排序總共進行至多n-1次交換。在所有的完全依靠交換去移動 元素的排序方法中,選擇排序屬於非常好的一種
三. 插入排序

插入排序是一種簡單直觀的排序演算法。它的工作原理是通過構建有序序列,對於未排序數據,在已排序序列中從後向前掃描,找到相應位置並插入。插入排序在從後向前掃描的過程中,需要反復把已排序元素逐步向後挪位,為最新元素提供插入空間
四. 快速排序
快速排序,又稱劃分交換排序。通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都要小,然後再按此方法對兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列
五 希爾排序過程

希爾排序是插入排序的一種,也稱縮小增量排序,是直接插入排序演算法的一種更高效的改進版本。希爾排序是非穩定排序演算法。希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序演算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,演算法便終止。
六. 歸並排序

歸並排序是採用分治法(把復雜問題分解為相對簡單的子問題,分別求解,最後通過組合起子問題的解的方式得到原問題的解)的一個非常典型的應用。歸並排序的思想就是先遞歸分解數組,再合並數組

將數組分解最小之後,然後合並兩個有序數組,基本思路是比較兩個數組的最前面的數,水小九先取誰,取了後相應的指針就往後移一位。然後比較,直至一個數組為空,最後把另一個數組的剩餘部分復制過來即可

4. c語言冒泡排序有什麼改進辦法嗎

1.設置一標志性變數pos,用於記錄每趟排序中最後一次進行交換的位置。由於pos位置之後的記錄均已交換到位,故在進行下一趟排序時只要掃描到pos位置即可。

改進後演算法如下:

voidBubble_1(intr[],intn){
inti=n-1;//初始時,最後位置保持不變
while(i>0){
intpos=0;//每趟開始時,無記錄交換
for(intj=0;j<i;j++)
if(r[j]>r[j+1]){
pos=j;//記錄交換的位置
inttmp=r[j];r[j]=r[j+1];r[j+1]=tmp;
}
i=pos;//為下一趟排序作準備
}
}

2.傳統冒泡排序中每一趟排序操作只能找到一個最大值或最小值,我們考慮利用在每趟排序中進行正向和反向兩遍冒泡的方法一次可以得到兩個最終值(最大者和最小者) ,從而使排序趟數幾乎減少了一半。

改進後的演算法實現為:

voidBubble_2(intr[],intn){
intlow=0;
inthigh=n-1;//設置變數的初始值
inttmp,j;
while(low<high){
for(j=low;j<high;++j)//正向冒泡,找到最大者
if(r[j]>r[j+1]){
tmp=r[j];r[j]=r[j+1];r[j+1]=tmp;
}
--high;//修改high值,前移一位
for(j=high;j>low;--j)//反向冒泡,找到最小者
if(r[j]<r[j-1]){
tmp=r[j];r[j]=r[j-1];r[j-1]=tmp;
}
++low;//修改low值,後移一位
}
}

5. 快速排序演算法

快速排序(Quicksort)是對冒泡排序的一種改進。

然後,左邊和右邊的數據可以獨立排序。對於左側的數組數據,又可以取一個分界值,將該部分數據分成左右兩部分,同樣在左邊放置較小值,右邊放置較大值。右側的數組數據也可以做類似處理。

重復上述過程,可以看出,這是一個遞歸定義。通過遞歸將左側部分排好序後,再遞歸排好右側部分的順序。當左、右兩個部分各數據排序完成後,整個數組的排序也就完成了。

快速排序演算法通過多次比較和交換來實現排序,其排序流程如下:

(1)首先設定一個分界值,通過該分界值將數組分成左右兩部分。

(2)將大於或等於分界值的數據集中到數組右邊,小於分界值的數據集中到數組的左邊。此時,左邊部分中各元素都小於或等於分界值,而右邊部分中各元素都大於或等於分界值。


6. 排序演算法使用(改進的)冒泡排序演算法。

#i nclude <stdlib.h>
#i nclude <time.h>

void maopao(int source[],int n)
{
int start=0,end=n-1;
int i;
while(start<=end)/*如果還有元素沒有確定其位置*/
{
for(i=start;i<end;i++)/*尋找剩餘元素的最大數*/
if(source[i]>source[i+1])
{
int t;
t=source[i];
source[i]=source[i+1];
source[i+1]=t;
}
end--;/*找到最大數*/
for(i=end;i>start;i--)/*尋找剩餘元素的最小元素*/
if(source[i]<source[i-1])
{
int t;
t=source[i];
source[i]=source[i-1];
source[i-1]=t;
}
start++;/*找到一個最小數*/
}
}

void output(int data[],int n)
{
int i;
for(i=0;i<n;i++)
{
if(i%10==0)
printf("\n");
printf("%4d",data[i]);
}
}

int check(int data[],int n)
{/*檢查結果數據是否已升序排列*/
int i;
for(i=0;i<n-1;i++)
if(data[i]>data[i+1])
return 0;
return 1;
}

void main()
{
int data[500];
int i;
srand(time(NULL));
for(i=0;i<500;i++)
data[i]=random(500);
printf("\nThe original data is:\n");
output(data,500);
maopao(data,500);
printf("\nAfter sort:\n");
output(data,500);
printf("\n");
if(check(data,500)==1)
printf("\nRight.");
else
printf("\nWrong.");
}

7. 數據結構中快速排序演算法的不足以及改進

一般快速排序演算法都是以最左元素作為劃分的基準值,這樣當數據元素本身已經完全有序(不管正序或者逆序)時,每一趟劃分只能將一個元素分割出來,其效率很低:時間復雜度O(n^2),空間復雜度為O(n)
所以改進方法就是找尋合適的基準值,保證不至於在關鍵字有序或者接近有序時發生這個情況,一般可以使用三者取中(就是待劃分序列的頭元素、尾元素、中間元素三者的中間值)、或者隨機選擇等方法,這樣即使關鍵字完全有序,也可以保證時間復雜度O(nlogn),空間復雜度O(logn)

8. 誰能給我幾種排序的具體演算法(直接插入,折半插入,冒泡,簡單選擇,快速,堆,歸並排序)

直接插入排序
說明:逐個將後一個數加到前面的排好的序中。在直接插入排序過程中,對其中一個記錄的插入排序稱為一次

排序;直接插入排序是從第二個記錄開始進行的,因此,長度為n的記錄序列需要進行n-1次排序才能完成整個

序列的排序。時間復雜度為O(n2)。
void InsertSort(elemtype x[],int n)
/*用直接插入法對x[0]-x[n-1]排序*/
{
int i,j;
elemtype s;
for(i=0;i<n-1;i++)
{
s=x[i+1];
j=i;
while(j>-1&&s.key<x[j].key)
{
x[j+1]=x[j];
j--;
}
x[j+1]=s;
}
}

---------------------
希爾排序
說明:希爾排序又稱縮小增量排序,增量di可以有各種不同的取法,但最後一次排序時的增量必須為1,最簡

單可取di+1=di/2(取小)。時間復雜度為O(n(log2n)2)。

void ShellSort(elemtype x[],int n,intd[],int Number)
/*用希爾排序法對記錄x[0]-x[n-1]排序,d為增量值數組*/
/*Number為增量值個數,各組內採用直接插入法排序*/
{
int i,j,k,m,Span;
elemtype s;
for(m=0;m<Number;m++)
{
Span=d[m];
for(k=0;k<Span;k++)
{
for(i=k;i<n-1;i+=Span)/*這個for之後的是「組內採用直接插入法排序」*/
{
s=x[i+Span];
j=i;
while(j>-1&&s.key<x[j].key)
{
x[j+Span]=x[j];
j-=Span;
}
x[j+Span]=s;
}
}
}
}

----------------------------
直接選擇排序
說明:每次將後面的最小的找出來插入前面的已排好的序中。同理,具有n個記錄的序列要做n-1次排序。
時間復雜度為O(n2)。
void SelectSort(elemtype x[],int n)
/*用直接選擇排序法對x[0]-x[n-1]排序*/
{
int i,j,Small;
elemtype Temp;
for(i=0;i<n-1;i++)
{
Small=i;
for(j=i+1;j<n;j++)
if(x[j].key<x[Small].key)
Small=j;

if(Small!=i)
{
Temp=x[i];
x[i]=x[Small];
x[Small]=Temp;
}
}
}

--------------------------
冒泡排序
說明:兩個兩個比較,將大的往後移。通過第一次冒泡排序,使得待排序的n個記錄中關鍵字最大的記錄排到

了序列的最後一個位置上。然後對序列中前n-1個記錄進行第二次冒泡排序。。。對於n個記錄的序列,共需進

行n次冒泡排序。時間復雜度為O(n2)。

void BubbleSort(elemtype x[],int n)
/*用冒泡排序法對x[0]-x[n-1]排序*/
{
int i,j,flag=1;
elemtype Temp;
for(i=1;i<n&&flag==1;i++)
{
flag=0;
for(j=0;j<n-i;j++)
{
if(x[j].key>x[j+1].key)
{
flag=1;
Temp=x[j];
x[j]=x[j+1];
x[j+1]=Temp;
}
}
}
}

-----------------------------
快速排序
說明:又叫分區交換排序,是對冒泡排序方法的一種改進。時間復雜度為O(nlog2n)。

void QuickSort(elemtype x[],int low,int high)
/*用遞歸方法對記錄x[0]-x[n-1]進行快速排序*/
{
int i,j;
elemtype Temp;

i=low;
j=high;
Temp=x[low];

while(i<j)
{
/*在序列的右端掃描*/
while(i<j&&Temp.key<=x[j].key)j--;
if(i<j)
{
x[i]=x[j];
i++;
}

/*在序列的左端掃描*/
while(i<j&&x[i].key<Temp.key)i++;
if(i<j)
{
x[j]=x[i];
j--;
}
}
x[i]=Temp;

/*對子序列進行快速排序*/
if(low<i-1)QuickSort(x,low,i-1);
if(j+1<high)QuickSort(x,j+1,high);
}

-------------------------
歸並排序
說明:所謂歸並排序就是將兩個或兩個以上的有序數據序列合並成一個有序數據序列的過程。
時間復雜度為O(nlog2n)。

void merge(r,l,m,h,r1,r2)/*r[l,m]及r[m+1,h]分別有序,歸並後置於r2中*/
sqlist r,r2;
int l,m,h;
{
int i,j,k;
k=l;/*k是r2的指示器,i、j分別為s1、s2的指示器*/
i=l;
j=m+1;

while(i<=m&&j<=h)
{
if(r[i].key<=r[j].key)
{
r2[k]=r[i];
i++;
}
else
{
r2[k]=r[j];
j++;
}
k++;
}
if(i>m) /*s1結束*/
while(j<=h)
{
r2[k]=r[j];
j++;k++;
}
else
while(i<=m)
{
r2[k]=r[i];
i++;k++;
}
}

9. 求一個插入排序和冒泡排序的改進演算法

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)

10. 快速排序演算法原理與實現

快速排序的原理:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小。

然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。

假設要排序的數組是A[1]……A[N],首先任意選取一個數據(通常選用第一個數據)作為關鍵數據,然後將所有比它的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一躺快速排序。一躺快速排序的演算法是:

1、設置兩個變數I、J,排序開始的時候I:=1,J:=N;

2、以第一個數組元素作為關鍵數據,賦值給X,即X:=A[1];

3、從J開始向前搜索,即由後開始向前搜索(J:=J-1),找到第一個小於X的值,兩者交換;

4、從I開始向後搜索,即由前開始向後搜索(I:=I+1),找到第一個大於X的值,兩者交換;

5、重復第3、4步,直到I=J。

(10)排序改進演算法擴展閱讀:

設要排序的數組是A[0]……A[N-1],首先任意選取一個數據(通常選用數組的第一個數)作為關鍵數據,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一趟快速排序。

值得注意的是,快速排序不是一種穩定的排序演算法,也就是說,多個相同的值的相對位置也許會在演算法結束時產生變動。

一趟快速排序的演算法是:

1、設置兩個變數i、j,排序開始的時候:i=0,j=N-1;

2、以第一個數組元素作為關鍵數據,賦值給key,即key=A[0];

3、從j開始向前搜索,即由後開始向前搜索(j--),找到第一個小於key的值A[j],將A[j]的值賦給A[i];

4、從i開始向後搜索,即由前開始向後搜索(i++),找到第一個大於key的A[i],將A[i]的值賦給A[j];

5、重復第3、4步,直到i=j; (3,4步中,沒找到符合條件的值,即3中A[j]不小於key,4中A[i]不大於key的時候改變j、i的值,使得j=j-1,i=i+1,直至找到為止。找到符合條件的值,進行交換的時候i, j指針位置不變。

熱點內容
資料庫中已存在 發布:2025-01-20 15:35:44 瀏覽:109
壓縮超過密度 發布:2025-01-20 15:35:33 瀏覽:647
和她在一起的日歷怎麼弄安卓 發布:2025-01-20 15:29:29 瀏覽:639
android6華為 發布:2025-01-20 15:28:06 瀏覽:692
荔枝fm怎麼上傳錄音 發布:2025-01-20 15:22:27 瀏覽:107
馬3智雅版有哪些配置 發布:2025-01-20 15:03:06 瀏覽:362
離心機編程 發布:2025-01-20 15:02:24 瀏覽:945
按鍵的匯編程序程序 發布:2025-01-20 15:01:04 瀏覽:555
linux有哪些系統 發布:2025-01-20 14:53:38 瀏覽:90
android顯示當前時間 發布:2025-01-20 14:53:29 瀏覽:968