/******************************************************************************************************************************** *功 能:各種排序演算法 *作 者:JarvisChu *時 間:2010-05-01 *知識點: 直接插入排序:1. 從i=2開始,如果L[i]>L[i-1],則進入2 2. L[0] = L[i],暫存L[i],我們成L[i]為待插入的元素 3. L[i] = L[i-1],將L[i-1]後移一位,佔領原來L[i]的位置 4. 將i-1之前的所有比待插入元素大的資料,都往後移動一位 5. 將待插入的元素插入到不比它大的數的後面一位 Shell排序思路:先將表分割成幾個小組,每個小組進行直接插入排序,然後整體進行一趟直接插入排序 理解:小組內進行的直接插入排序使得key小的元素能迅速跳躍式的移動到前面,key大的元素能跳躍式的移動到後面 *********************************************************************************************************************************/#include <iostream>using namespace std;#define MAX_ARRAY_SIZE 300typedef int ElemType; //元素類型/*靜態尋找表的順序儲存結構*/typedef struct{ ElemType elem[MAX_ARRAY_SIZE]; int length;}SSTable;/*初始化靜態尋找表*/bool InitSSTable(SSTable* pSSTable){ pSSTable->length = 8; //實際的元素個數 pSSTable->elem[0] = 0;//監察哨 pSSTable->elem[1] = 49;// pSSTable->elem[2] = 38;// pSSTable->elem[3] = 65;// pSSTable->elem[4] = 97;// pSSTable->elem[5] = 76;// pSSTable->elem[6] = 13;// pSSTable->elem[7] = 27;// pSSTable->elem[8] = 49;// return true;}/*顯示出靜態表*/void DisplaySSTable(SSTable table){ for(int i=1;i<=table.length;i++){ cout<<table.elem[i]<<", "; } cout<<endl;}/*直接插入排序 O(n*n)*/void InsertSort(SSTable* pSSTable){ for(int i=2;i<=pSSTable->length;i++){ if(pSSTable->elem[i] < pSSTable->elem[i-1]){ pSSTable->elem[0] = pSSTable->elem[i]; pSSTable->elem[i] = pSSTable->elem[i-1]; int j=i-2; while(pSSTable->elem[0]<pSSTable->elem[j]){//凡是比它大的都往右移動 pSSTable->elem[j+1] = pSSTable->elem[j]; j--; }/* int j; for(j=i-2;pSSTable->elem[0] < pSSTable->elem[j];j--){ // cout<<"將"<<pSSTable->elem[j]<<"移動到"<<pSSTable->elem[j+1]<<endl; pSSTable->elem[j+1] = pSSTable->elem[j]; }*/ pSSTable->elem[j+1] = pSSTable->elem[0]; } }}/*折半插入排序 O(n*n)*/void BInsertSort(SSTable* pSSTable){ for(int i=2;i<=pSSTable->length;i++){ pSSTable->elem[0] = pSSTable->elem[i]; int low = 1; int high = i-1; while(low<=high){ int mid = (low+high)/2; if(pSSTable->elem[mid]>pSSTable->elem[0]) high = mid-1;//在下半區 else low = mid+1; //在上半區 } //high+1就是應該插入的位置 for(int j=i-1;j>=high+1;j--){ pSSTable->elem[j+1] = pSSTable->elem[j]; } pSSTable->elem[high+1] = pSSTable->elem[0]; }}/*一趟以dk為增量的Shell插入排序*/void ShellInsert(SSTable* pT,int dk){ for(int group=1;group<=dk;group++){//分成dk個小組 for(int i=group+dk;i<=pT->length;i+=dk){//對每一個小組進行直接插入排序 if(pT->elem[i] < pT->elem[i-dk]){//當前元素值,比它這個小組內的前一個元素值小 pT->elem[0] = pT->elem[i];//當前的元素暫時放在 0 處儲存 pT->elem[i] =pT->elem[i-dk];//將前一個元素移動到當前位置 int j = i-2*dk;//小組內,當前位置的前面第二個 while(j>=group+dk && pT->elem[j] > pT->elem[0]){// j>= 該小組的第一個元素的位置,且,pT[j]大於要比較的元素 pT->elem[j+dk] = pT->elem[j]; j -= dk; } pT->elem[j+dk] = pT->elem[0]; } } }}/*Shell插入排序,用增量序列dlta,對pSSTable所指向的表做t次直接插入排序*/void ShellSort(SSTable* pSSTable,int dlta[], int t){ for(int k=0;k<t;k++){ ShellInsert(pSSTable,dlta[k]); }}/*冒泡排序(交換排序)*/void BubbleSort(SSTable* pT){ for(int i=1;i<pT->length;i++){//控制排序趟數,共pT->length-1趟 for(int j =1;j <= pT->length-i;j++){ if(pT->elem[j] > pT->elem[j+1]){ ElemType temp = pT->elem[j+1]; pT->elem[j+1] = pT->elem[j]; pT->elem[j] = temp; } } }}/*Partition函數,完成一趟快速排序,並返回軸位置*/int Partition(SSTable* pT,int low,int high){ int pivot = pT->elem[low];//以最低位為軸 while(low < high){ while(low < high && pT->elem[high] >= pivot) high--; pT->elem[low] = pT->elem[high]; while(low < high && pT->elem[low] <= pivot) low++; pT->elem[high] =pT->elem[low]; } pT->elem[low] = pivot; return low;}/*快排 O(nlogn)*/void QSort(SSTable* pT,int low,int high){ if(low < high){ int pivot = Partition(pT,low,high); QSort(pT,low,pivot-1); QSort(pT,pivot+1,high); }}/*簡單選擇排序*/void SelectSort(SSTable* pT){ for(int i=1;i<=pT->length-1;i++){ for(int j=i+1;j<=pT->length;j++){ if(pT->elem[j] < pT->elem[i]){ ElemType temp = pT->elem[j]; pT->elem[j] = pT->elem[i]; pT->elem[i] = temp; } } }}int main(){ SSTable ST;/* 直接插入排序 InitSSTable(&ST); InsertSort(&ST); DisplaySSTable(ST);*//* 折半插入排序 InitSSTable(&ST); BInsertSort(&ST); DisplaySSTable(ST);*//* Shell排序 InitSSTable(&ST); int dlta[4] = {5,3,2,1}; ShellSort(&ST,dlta,4); DisplaySSTable(ST);*//* 冒泡排序 InitSSTable(&ST); BubbleSort(&ST); DisplaySSTable(ST);*//* 快排 InitSSTable(&ST); QSort(&ST,1,ST.length); DisplaySSTable(ST);*//* 簡單選擇排序 InitSSTable(&ST); SelectSort(&ST); DisplaySSTable(ST);*/ return 0;}