數據結構筆記(排序技術)

  • /**

  • 排序技術的概念

  •     排序:

  •     正序:按關鍵碼排好序

  •     逆序(反序): 與正序序列順序相反

  •     趟: 在排序過程中, 將待排序的記錄序列掃描一遍稱爲一趟

  •         排序算法的穩定性: 假定在待排序的記錄集中, 存在多個具有相同

  •         鍵值的記錄, 若經過排序 這些記錄的相對次序仍然保持不變, 即

  •         排序算法具有穩定性(效率高的算法一般不穩定, 效率低的算法一

  •         般穩定)

  •     時間複雜度:

  •         比較: (關鍵碼之間的比較)

  •         移動: (記錄從一個位置移動到另一一個位置)

  •     空間複雜度: 輔助存儲空間

  •         輔助存儲空間是指在數據規模一定的條件下, 除了存放待排序記錄

  •         佔用的存儲空間之外, 執行算法所需要的其他存儲空間

  • **/

  • /**

  • 插入類排序

  •     主要操作: 插入

  •     基本思想: 每次將一個待排序的記錄按其關鍵碼的大小插入到一個已經

  •     排好序的有序序列中, 直到全部記錄排好序爲止

  •     方法:

  •         直接插入排序

  •             基本思想: 在插入第i (i>1) 個記錄時, 前面的 i-1 個記錄已

  •                        經排好序

  •             解決方法: 將第一個記錄看成是初始有序表, 然後從第2個記錄

  •                       其依次插入到這個有序表中, 直到第n個記錄的插入

  •             最好情況(正序): 比較次數n-1, 移動次數2(n-1)

  •                 時間複雜度: O(n)

  •             最壞情況(逆序):

  •                 時間複雜度O(n^2)

  •             平均情況: 時間複雜度O(n^2), 空間複雜度O(1)

  •             適用於待排序記錄基本有序, 或者排序記錄個數較小

  •         希爾排序(減小增量的排序)

  •             基本思想: 將整個待排序記錄分割成若干個子序列

  •                        在子序列內分別進行直接插入排序

  •                        待排序序列中的記錄基本有序時, 對全體記錄進行

  •                        直接插入排序

  •             解決方法: d=n/2, d(i+1)=d(i)/2

  •                        即for(int d=n/2;d>=1;d=d/2)

  •             時間複雜度: O(nlog_2~n)

  • **/

  • /**

  • 交換排序

  •     主要操作: 交換

  •     主要思想: 在待排序列中選兩個記錄, 將它們的關鍵碼相比較, 如果反

  •     序(即排列順序與排序後的次序正好相反), 則交換它們的存儲位置

  •     方法:

  •         冒泡排序:

  •             基本思想: 基本思想:兩兩比較相鄰記錄的關鍵碼, 如果反序則

  •                        交換, 直到沒有反序的記錄爲止

  •             最好情況: 比較次數n-1, 移動次數0

  •                 時間複雜度: O(n)

  •             最壞情況:

  •                 時間複雜度: O(n^2)

  •             平均情況: 時間複雜度O(n^2)

  •         快速排序:

  •                 基本思想: 首先選一個軸值(即比較的基準)通過一趟排序將

  •                            待排序記錄分割成獨立的兩部分, 前一部分記

  •                            錄的關鍵碼均小於或等於軸值, 後一部分記錄

  •                            的關鍵碼均大於或等於軸值然後分別對這兩部

  •                            分重複上述方法, 直到整個序列有序

  •                 時間複雜度: O(nlog_2~n)

  • **/

  • /**

  • 選擇排序

  •     簡單選擇排序:

  •         基本思想: 第i趟在n-i+1(i=1, 2, ..., n-1)個記錄中選取關鍵碼最

  •         小的記錄作爲有序序列中的第i個記錄

  •     堆排序

  • **/

  • #include<iostream>

  • using namespace std;

  • //數組複製

  • void copyArray(int data[],int data0[],int n){

  •     for(int i=1;i<=n;i++){

  •         data0[i]=data[i];

  •     }

  • }

  • //直接插入排序

  • void insertSort(int data[],int n){

  •     for(int i=2;i<=n;i++){

  •         data[0]=data[i];

  •         int j=i-1;

  •         while(data[j]>data[0]){

  •             data[j+1]=data[j];

  •             j--;

  •         }

  •         data[j+1]=data[0];

  •     }

  • }

  • //希爾排序

  • void xierSort(int data[],int n){

  •     for(int d=n/2;d>=1;d=d/2){

  •         for(int i=d+1;i<=n;i++){

  •             data[0]=data[i];

  •             int j=i-d;

  •             while(j>0&&data[j]>data[0]){

  •                 data[j+d]=data[j];

  •                 j-=d;

  •             }

  •             data[j+d]=data[0];

  •         }

  •     }

  • }

  • //冒泡排序

  • void maopaoSort(int data[],int n){

  •     for(int i=1;i<=n;i++){

  •         int exchange=0;

  •         for(int j=1;j<=n-i;j++){

  •             if(data[j+1]<data[j]){

  •                 data[0]=data[j];

  •                 data[j]=data[j+1];

  •                 data[j+1]=data[0];

  •                 exchange=1;

  •             }

  •         }

  •         if(exchange==0) break;

  •     }

  • }

  • //快速排序

  • int myPartition(int data[],int first,int last){

  •     int i=first;

  •     int j=last;

  •     data[0]=data[i];

  •     while(i<j){

  •         while(i<j&&data[0]<=data[j]) j--;

  •         if(i<j){

  •             data[i]=data[j];

  •             i++;

  •         }

  •         while(i<j&&data[0]>=data[i]) i++;

  •         if(i<j){

  •             data[j]=data[i];

  •             j--;

  •         }

  •     }

  •     data[i]=data[0];

  •     return i;

  • }

  • void mySort(int data[],int first,int last,int n){

  •     if(first<last){

  •         int p=myPartition(data,first,last);

  •         mySort(data,first,p-1,n);

  •         mySort(data,p+1,last,n);

  •     }

  • }

  • //簡單選擇排序

  • void jianDanSort(int data[],int n){

  •     for(int i=1;i<=n;i++){

  •         data[0]=data[i];

  •         int index=i;

  •         for(int j=i+1;j<=n;j++){

  •             if(data[j]>data[0])

  •                 index=j;

  •         }

  •         if(index!=i){

  •             data[0]=data[i];

  •             data[i]=data[index];

  •             data[index]=data[0];

  •         }

  •     }

  • }

  • int main(){

  •     int n;

  •     int data[100];

  •     int data0[100];

  •     cin>>n;

  •     for(int i=1;i<=n;i++)

  •         cin>>data[i];

  •     cout<<"插入排序"<<endl;

  •     copyArray(data,data0,n);

  •     insertSort(data,n);

  •     for(int k=1;k<=n;k++)

  •         cout<<data[k]<<" ";

  •     cout<<endl;

  •     cout<<"希爾排序"<<endl;

  •     copyArray(data0,data,n);

  •     xierSort(data0,n);

  •     for(int k=1;k<=n;k++)

  •         cout<<data0[k]<<" ";

  •     cout<<endl;

  •     cout<<"冒泡排序"<<endl;

  •     copyArray(data,data0,n);

  •     maopaoSort(data,n);

  •     for(int k=1;k<=n;k++)

  •         cout<<data[k]<<" ";

  •     cout<<endl;

  •     cout<<"快速排序"<<endl;

  •     copyArray(data0,data,n);

  •     mySort(data0,0,n,n);

  •     for(int k=1;k<=n;k++)

  •         cout<<data0[k]<<" ";

  •     cout<<endl;

  •     copyArray(data,data0,n);

  •     jianDanSort(data,n);

  •     for(int k=1;k<=n;k++)

  •         cout<<data0[k]<<" ";

  •     cout<<endl;

  • }

  •  

  • /**

  • 簡單選擇排序

  • 基本思想: 第i趟在n-i+1(i=1,2,...,n-1)個記錄中選取關鍵碼最小的記錄作爲有序序列的第i個記錄

  • 解決方法: 設置一個整型變量index, 用於記錄在一趟比較過程中關鍵碼最小的記錄位置

  • 簡單選擇排序算法性能分析

  • 時間複雜度O(n^2)

  • 空間複雜度O(1)

  • 簡單選擇排序是不穩定的

  • 堆排序

  • 減少關鍵碼間的比較次數

  • 查找最小值的同時, 找出最小值

  • 堆是具有下列性質的完全二叉樹: 每個結點的值都小於或等於其左右孩子結點的值(稱爲小根堆)

  • 或每個結點的值都大於或等於其左右孩子結點的值(稱爲大根堆)

  • 小根堆的根結點是所有結點的最小值

  • 較小結點靠近根結點,但不絕對

  • 大根堆的根結點是所有結點中的最大者
     

  • 較大結點靠近根節點, 但不絕對

  • 將堆用順序存儲結構來存儲, 則堆對應一組序列

  • 基本思想:

  • 首先將待排序的記錄序列構造成一個堆(大頂堆)

  • 此時, 選出了堆中所有記錄的最大者, 然後將它從堆中移走

  • 將剩餘的記錄在調整成堆

  • 這樣又找出了次大的記錄, 以此類推, 直到堆中只有一個記錄

  • **/

  • #include<iostream>

  • using namespace std;

  • void selectSort(int a[],int n){

  •     for(int i=1;i<=n;i++){

  •         int index=i;

  •         for(int j=i+1;j<=n;j++)

  •             if(a[j]<a[index]) index=j;

  •         if(index!=i){

  •             a[0]=a[i];

  •             a[i]=a[index];

  •             a[index]=a[0];

  •         }

  •     }

  • }

  • void sift(int a[],int k,int m){

  •     int i=k;

  •     int j=2*i;

  •     a[0]=a[i];

  •     while(j<=m){

  •         if(j<m&&a[j]<a[j+1]) j++;

  •         if(a[0]>a[j]) break;

  •         else{

  •             a[i]=a[j];i=j;j=2*i;

  •         }

  •     }

  •     a[i]=a[0];

  •     for(int k=1;k<=5;k++)

  •         cout<<a[k]<<" ";

  •     cout<<endl;

  • }

  • void heapSort(int a[],int n){

  •     for(int i=n/2;i>=1;i--)

  •         sift(a,i,n);

  •     for(int i=1;i<n;i++){

  •         a[0]=a[1];

  •         a[1]=a[n-i+1];

  •         a[n-i+1]=a[0];

  •         sift(a,1,n-i);

  •     }

  • }

  • int main(){

  •     int a[6]={0,34,67,21,43,56};

  •     heapSort(a,5);

  •     for(int i=1;i<=5;i++)

  •         cout<<a[i]<<" ";

  • }

  •  
發佈了21 篇原創文章 · 獲贊 4 · 訪問量 2518
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章