1. 程式人生 > >內部排序演算法的實現與比較-資料結構課程設計

內部排序演算法的實現與比較-資料結構課程設計

內部排序演算法的實現與比較

1) 問題描述

在教科書中,各種內部排序演算法的時間複雜度分析結果只給出了演算法執行時間的階,或大概執行時間。試通過隨機資料比較各演算法的關鍵字比較次數和關鍵字移動次數,以取得直觀感受。

2)基本要求

(1) 對常用的內部排序演算法進行比較:直接插入排序、簡單選擇排序、氣泡排序、快速排序、希爾排序、歸併排序。

(2) 利用隨機函式產生NN=30000)個隨機整數,作為輸入資料作比較;比較的指標為關鍵字參加的比較次數和關鍵字的移動次數(關鍵字交換計為3次移動)。

(3) 對結果作出簡要分析。

3)測試資料

隨機函式產生。

4)提示

主要工作是設法在已知演算法中適當位置插入對關鍵字的比較次數和移動次數的計數操作。注意採用分塊除錯的方法。

5)輸入輸出:

輸入資料:參加排序的整數個數NN=30000,注:不得減少N);

輸出資料:各種排序方法的關鍵字比較次數和移動次數(從小到大排列)。

本來氣泡排序交換次數想用樹狀陣列BIT發現數據太多時 用BIT加的資料會超限 所以還是直接用了氣泡排序 

上程式碼--純C語言:

/*
*   zhagoodwell 查昊昊QQ微信:2423824433 
*  直接插入: charu函式
*  選擇:  xuanzepai函式 
*  冒泡:  maopao函式
*  快排: Qsort 遞迴函式 
*  希爾:shell 函式 
*  歸併:GB 函式 
*/ 
# include <stdio.h>  
# include <stdlib.h>
# include <time.h>
# define N 30000
# define SR 1001
int A[N],B[N],C[N],D[N],E[N],F[N],G[N];
int a,aa,b,bb,d,dd,e,ee,f,ff,num;   //單個字母的為記錄的比較次數-移動的次數,雙字母為關鍵字的移動次數 
long long c,cc;
void charu(int A[],int n);//對n個元素                     直接插入排序
void xuanzepai(int A[],int n);//對n個元素                  選擇升序 
void maopao(int A[],int n);  //                            氣泡排序 
void Quicksort(int A[],int L,int R);//對[L,R]個元素       快速升序
void shell(int A[],int n);//對n個元素                     shell 升序 
void GBPX(int S[],int L,int R,int T[]);//                  歸併排序 
int GB(int S[],int L,int M,int R,int T[]);//陣列歸併操作    
int gainint(int *p,int min,int max);//防輸錯而建的函式    *p的範圍[min,max] 
int change(int *a,int *b);//交換函式                      交換a b的值 
void charu(int A[],int n)//返回迴圈比較次數 
{  
    int i,j,temp;  
    for (i=1,a++;i<n;i++,a++)  
        if (A[i]<A[i-1])  
        {   
            temp=A[i];
            for(a++,aa++,j=i-1;j>=0&& A[j]>temp;j--,a++,aa++)
            	A[j+1]=A[j];
            A[j+1]=temp;
        }  
}  
void xuanzepai(int A[],int n)//以A[0]為比較依據 升序  
{  
    int i,j,k;  
    for(i=0,b++;i<n-1;i++,b++)  
    {  
       k=i;  
       for(j=i+1,b++;j<n;j++,b++)  
          if(A[j]<A[k])  
              { k=j;b++;}  
       if(k!=i)    
       {
          bb+=change(&A[i],&A[k]);   
       }
    }   
} 
void maopao(int A[],int n)  
{  
    int i,j;  
    for (i = n -1 ; i>=0 ;i--)  
    {  
        for (j = 0; j<i; j++)  
        {  
            if(A[j]>A[j+1])
              cc+=change(&A[j],&A[j+1]);
        }  
    }  
}  
void Quicksort(int A[],int L,int R)//快速排序 升序   
{  
    int i=L,j=R,T=A[L]; //T為基準數  
    if(L>R)  return;  
    while(i!=j) //當陣列左右兩邊沒相遇  
    {  
        while(A[j]>=T&&i<j){j--;d++;}  //從右向左找
        while(A[i]<=T&&i<j){i++;d++;} //從左向右找   
        if(i<j)dd+=change(&A[i],&A[j]); //交換兩數  
    }  
    if(L!=i)
        dd+=change(&A[L],&A[i]);       //基準數歸位  
    Quicksort(A,L,i-1);         //遞迴左  
    Quicksort(A,i+1,R);         //遞迴右  
}  
void shell(int A[],int n)//希爾排序 增量為2 
{
	int i,j,k;
	for(k=n>>1,e++;k>0;k=k>>1,e++)
	{
		for(i=k,e++;i<n;i++,e++)
		{
			for(j=i-k,e++;j>=0;j-=k,e++)
			    if(A[j]>A[j+k])
			       ee+=change(&A[j],&A[j+k]);
		}
	}
}
int GB(int S[],int L,int M,int R,int T[])//陣列歸併操作  
{  
    int i=M,j=R,k=0,count=0;  
    while(i>=L&&j>M)  
    {  
        f++;
        if(S[i]>S[j])  
        {  
            T[k++]=S[i--];//從臨時陣列的最後一個位置開始排序  
              
        }  
        else  T[k++]=S[j--];   
        count++;
    }  
    
    while(i>=L){f++;T[k++]=S[i--];} //若前半段陣列還有元素未放入臨時陣列T中  
    while(j>M){f++;T[k++]=S[j--];}     
    for(i=0,f+=k;i<k;i++)  S[R-i]=T[i];//寫回原陣列
    return count;  
}  
void GBPX(int S[],int L,int R,int T[])  
{  
    int M;    
    if(L<R)  
    {  
        M=(L+R)>>1;  
        GBPX(S,L,M,T);//找左半段的逆序對數目  
        GBPX(S,M+1,R,T);//找右半段的逆序對數目  
        ff+=GB(S,L,M,R,T);//找完左右半段逆序對以後兩段陣列有序,找兩段之間的逆序對。  
    }     
}  
int gainint(int *p,int min,int max)//輸入int *p直至滿足(a,b)輸入結束,並返回*p的位數          
{           
    do{          
        *p=min-1;    //此處是為了減少意外情況的發生 雖然那種意外情況不常見    
        scanf("%d",p);          
        while(getchar()!='\n');          
        if(*p>max||*p<min)          
            printf("輸入有誤,請重新輸入[%d--%d]:",min,max);          
    }while(*p>max||*p<min);          
    return *p;          
}  
int change(int *a,int *b)//交換函式                       交換a b的值   
{  
    int c=*a;  
    *a=*b;  
    *b=c;  
    return 3;
}  
int main(){    
    int i,t; 
    srand(time(0));
    printf("請輸入N [2,%d]:",N);
    gainint(&num,2,N);
    for(i=0;i<num;i++)
     printf("%d\t",A[i]=B[i]=C[i]=D[i]=E[i]=F[i]=rand()%SR);
    charu(A,num);
    printf("\n直接插入排序:\n比較次數:%10d\t移動次數%10d\n\n",a,aa);
    xuanzepai(B,num);
    printf("簡單選擇排序:\n比較次數:%10d\t移動次數%10d\n\n",b+bb/3,bb);
    c=(num-1)*num/2;
    maopao(C,num); 
    printf("氣泡排序:\n比較次數:%10lld\t移動次數%10lld\n\n",c+cc/3,cc);
    Quicksort(D,0,num-1);
    printf("快速排序:\n比較次數:%10d\t移動次數%10d\n\n",d+dd/3,dd);
    shell(E,num);
    printf("希爾排序:\n比較次數:%10d\t移動次數%10d\n\n",e+ee/3,ee);
    GBPX(F,0,num-1,G);
    printf("歸併排序:\n比較次數:%10d\t移動次數%10d\n\n",f,ff);
    printf("按任意鍵繼續……");
	getchar(); 
    return 0;  
}  


相關推薦

內部排序演算法實現比較-資料結構課程設計

內部排序演算法的實現與比較 1) 問題描述 在教科書中,各種內部排序演算法的時間複雜度分析結果只給出了演算法執行時間的階,或大概執行時間。試通過隨機資料比較各演算法的關鍵字比較次數和關鍵字移動次數,以取得直觀感受。 2)基本要求 (1) 對常用的內部排序演算法進行比較:直接

排序演算法(天勤資料結構高分筆記)

排序演算法 直接插入排序演算法:每趟將一個待排序的關鍵字按照其值的大小插入到已經排好的部分有序序列的適當位置上,直到所有待排關鍵字都被插入到有序序列中為止 void InsertSort(int R[], int n)    //代拍關鍵字儲存在R[]中,預設為

高階排序演算法實現優化

本文用到的測試資料生成的程式碼和分析:《測試資料自動生成》 文章圖片來源於 GitHub,網速不佳的朋友請點我看原文。 順便軟廣一下個人技術小站:godbmw.com。歡迎常來 ♪(^∇^*) 1. 談談高階排序 本文主要介紹高階排序演算法中的歸併排序和快速排序。他們有運用了分支思想,並且大多通過遞迴來實現。

氣泡排序和選擇排序實現比較

氣泡排序: 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。 針對所有的元素重複以上的步驟,除了最後一個。 持續每次對越來越少的元素重複上面的步驟,直到沒有任何一

9種常見內部排序演算法的效能比較

       在寫完這9種常見的內部排序演算法後總覺得需要把它們拿出來好好比較一番,看看各個演算法的效能優劣。        我們先來看看這九種排序演算法的時間複雜度、空間複雜度和穩定性:  看完了各個排序演算法的理論效能後,再來看一看在實踐上的效能。        

各種排序演算法分析比較

1.直接插入排序 每一趟將一個待排序的元素作為關鍵字,按照其關鍵字的大小插入到已經排好的部分序列的適當位置上。平均時間複雜度為O(n2),空間複雜度為O(1)。 void InsertSort(int R[], int n) { if (R == nullptr ||

C語言 佇列的鏈式結構實現表示 資料結構 佇列的實現表示

  五一放假,也沒有什麼事情可以做的,本來想出去玩一玩或者打打球什麼的,可是天公不作美,這兩天天氣一直是在下雨,弄的人的心情溼透了。  昨天學習了一天的棧和佇列,昨天在下午些的時候完成了棧的程式設計工作。晚上本應該是用來寫完佇列的程式的,可是晚上到寢室熄燈之前只是差一點程式就

資料結構課程設計---------用棧來實現表示式求值

1、需求分析 設計一個程式,演示用算符優先法對算術表示式求值的過程。利用算符優先關係,實現對算術四則混合運算表示式的求值。 (1)輸入的形式:表示式,例如2*(3+4)      包含的運算子只能有'+' 、'-' 、'*' 、'/' 、'('、 ')'; (2)輸出的形式

資料結構課程設計農夫過河

此部落格是隻是為了演示程式碼的執行結果 下面是一個程式執行的結果(實現了兩種過河方案)    部分程式碼截圖 原始碼下載地址 https:

資料結構課程設計-檢查網路(並查集)

檢查網路 給定一個計算機網路以及機器間的雙向連線列表,每一條連線與允許兩端的計算機進行直接的檔案傳輸,其他計算機間若存在一條連通路徑,也可以進行間接的檔案傳輸。 要求實現功能: 任意指定兩臺計算機,判斷整個網路中是否任意兩臺機器間都可以檔案傳輸?若不可以,請給出當前網路

資料結構課程設計——學生資訊管理系統

/*Copyright (c)2017,煙臺大學計算機與控制工程學院 *All rights reservrd. *作者:趙楷文 *完成時間:2017年12月20日 *版本號:v1.0 *問題描述:設計一個管理學生資訊的

學生成績管理系統(資料結構課程設計

學生成績管理問題  問題描述:建立兩個學生成績資訊表1、2,以檔案的形式分別進行儲存命名為1.txt和2.txt,然後實現將兩個檔案合併成一個新的檔案3.txt。 新檔案中有補考的學生查詢到,儲存到另一個檔案4.txt中。     基本要求:    

資料結構課程設計-哈夫曼編碼譯碼

//******************************************** //程式功能:哈夫曼編碼及譯碼 // //日期:2014年11月18 // //******************************************** #incl

資料結構課程設計-哈夫曼樹及其應用

題目:假設用於通訊的電文由字符集{a,b,c,d,e,f,g,h,}中的字母構成,這8個字母在電文中出現的 頻率分別為: {0.19, 0.21, 0.02, 0.03, 0.06, 0.07, 0.1, 0.32}. 要求:畫出哈夫曼樹。 我從課本上面摘抄了一個題

資料結構課程設計~校園導航問題

校園導航問題 下邊發一下資料結構的課程設計:校園導航問題。 設計內容 (1)設計學校的平面圖(至少包括10個以上的場所)。每兩個場所間可以有不同的路徑,且路長也可能不同(圖形結構要求通過鍵盤輸入資料後採用建立圖的演算法生成圖形); (2)提供起始點與終點能自動找出從任意場所到達另

資料結構課程設計實驗報告

《演算法與資料結構》課程設計報告                                        資料結構課程設計是在學完資料結構課程之後的實踐教學環節。本實踐教學是培養學生資料抽象能力,進行復雜程式設計的訓練過程。要求學生能對所涉及問題選擇合適的資料結構

資料結構課程設計之銀行活期儲存系統(設計報告)

 C作為系統描述語言,既可以用來編寫系統軟體,也可以用來編寫應用軟體。C語言誕生後,許多原來用匯編語言編寫的軟體,現在都可以用C語言編寫;C++是一種靜態資料型別檢查的,支援多重程式設計正規化的通用程式設計語言。它支援過程化程式設計、資料

資料結構課程設計—學生資訊管理系統

問題描述: /* * Copyright (c)2015,煙臺大學計算機與控制工程學院 * All rights reserved. * 檔名稱:aaaa.cbp * 作 者:張芸嘉 * 完成日期:2015年12月24日 * 版 本

資料結構——課程設計之~安排教學計劃

1. 問題描述 大學的每個專業都要制訂教學計劃。假設任何專業都有固定的學習年限,每學年含兩個學期,每學期的時間長度和學分上限值均相等。每個專業開設的課程都是確定的,而且課程在開設時間的安排必須滿足先修關係。每門課程有哪些先修課程是確定的,可以有任意多門,也可以沒有。每門課恰

資料結構課程設計-學生資訊管理系統

/* * 煙臺大學計算機與控制工程學院 *檔名稱:mian.cpp *作 者:王旭 *完成日期:2015年12月25日 *版 本 號:v1.0 *