-
/**
-
排序技術的概念
-
排序:
-
正序:按關鍵碼排好序
-
逆序(反序): 與正序序列順序相反
-
趟: 在排序過程中, 將待排序的記錄序列掃描一遍稱爲一趟
-
排序算法的穩定性: 假定在待排序的記錄集中, 存在多個具有相同
-
鍵值的記錄, 若經過排序 這些記錄的相對次序仍然保持不變, 即
-
排序算法具有穩定性(效率高的算法一般不穩定, 效率低的算法一
-
般穩定)
-
時間複雜度:
-
比較: (關鍵碼之間的比較)
-
移動: (記錄從一個位置移動到另一一個位置)
-
空間複雜度: 輔助存儲空間
-
輔助存儲空間是指在數據規模一定的條件下, 除了存放待排序記錄
-
佔用的存儲空間之外, 執行算法所需要的其他存儲空間
-
**/
-
/**
-
插入類排序
-
主要操作: 插入
-
基本思想: 每次將一個待排序的記錄按其關鍵碼的大小插入到一個已經
-
排好序的有序序列中, 直到全部記錄排好序爲止
-
方法:
-
直接插入排序
-
基本思想: 在插入第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]<<" ";
-
}
數據結構筆記(排序技術)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.