#include "Sort.h"#include <iostream>using namespace std;Sort::Sort(void){}Sort::~Sort(void){}//冒泡排序//原理:每趟排序是通過比較兩兩相鄰的元素,大的向後移動,一趟//完後,最大的移動到最後,共需要size-1趟排序,特殊情況下,某趟未//移動任何元素,則說明序列已然有序,則排序完畢,此時趟數<size-1void Sort::maoPao(int data[],int size){ //換序標誌,如果本趟沒任何交換,表示已有序,退出 bool flag = true; //需要size-1趟排序 for (int i = 0; i < size - 1; i++) { //已有序,退出 if (!flag) break; //先設為已有序, flag = false; for (int j = 0; j < size - i - 1; j++ ) { //換序 if (data[j] > data[j + 1]) { swap(data,j,j + 1); //需要下一趟 flag = true; } } } print(data,size);}//選擇排序//原理:每次選擇都是從序列中選擇最小的元素,放到序列前面,共需size-1次選擇void Sort::xuanZe(int data[],int size){ //需要size-1次選擇 for (int i = 1; i < size; i++) { //記錄最小值下標 int k = i - 1; for (int j = i; j < size; j++) { if (data[j] < data[k]) k = j; } if (k != i - 1) swap(data,k,i - 1); } print(data,size);}//直接插入排序//原理:將序列分為有序和無序兩部分,每次排序需要將無序區的一個元素//插入到有序區的合適位置,需要size-1次排序void Sort::chaRu(int data[],int size){ //data[0]為有序區,[1,size-1]為無序區, //一次遍曆無序區元素插入到有序區 for (int i = 1; i < size; i++) { int temp = data[i]; int j = i - 1; for (; j >=0 && data[j] > temp; j--) { swap(data,j,j+1); } data[j + 1] = temp; } print(data,size);}//歸併排序//原理:一次歸併可描述為,將一個序列分成兩組,將這兩組歸併為一個有序的新序列,//歸併排序就是遞迴的進行上述操作(遞迴棧的最底部是將序列分成了[一個元素]、[一個元素]//這樣的兩組),我的表達能力也就到這了void Sort::guiBing(int data[],int size){ mergeSort(data,0,size - 1); print(data,size);}void Sort::mergeSort(int data[],int first,int last){ //遞迴出口,只歸併長度大於1的數組 if (first < last) { int mid = (first + last)/2; //遞迴左半組 mergeSort(data,first,mid); //遞迴右半組 mergeSort(data,mid + 1,last); //左右半組都排好後,再對著兩組排序 merge(data,first,mid,last); } }//歸併兩個數組[first,mid]、[mid+1,last],最後合并為一個有序的數組[first,last]void Sort::merge(int data[],int first,int mid,int last){ int *temp = new int[last - first + 1]; int k = 0; int index1 = first; int index2 = mid + 1; while (index1 <= mid && index2 <= last) { if (data[index1] <= data[index2]) temp[k++] = data[index1++]; else temp[k++] = data[index2++]; } while (index1 <= mid) temp[k++] = data[index1++]; while (index2 <= last) temp[k++] = data[index2++]; for (int i = 0; i < k; i++) data[first + i] = temp[i]; delete[] temp;}//快速排序//原理:一次快排可描述為,將序列分成三部分[左邊組都小於中間數]、[中間數]、[右邊組都大於中間數]//快排就是再遞迴的對左邊組和右邊組進行上述操作void Sort::kuaiPai(int data[],int size){ quickSort(data,0,size - 1); print(data,size);}void Sort::quickSort(int data[],int left,int right){ //遞迴出口 if (left < right) { int mid = partion(data,left,right); quickSort(data,left,mid - 1); quickSort(data,mid + 1,right); }}//一趟分組,執行完後分為左右兩組,左組都小於中間數,右組都大於中間數int Sort::partion(int data[],int left,int right){ //第一個數做中間值 int temp = data[left]; int leftIndex = left; int rightIndex = right; //相等時退出 while (leftIndex < rightIndex) { //從右邊找到數值<temp的數 while (leftIndex < rightIndex && data[rightIndex] >= temp) rightIndex--; //把找到的數放到中間數位置,此時data[rightIndex]相當於中間數位置 if (leftIndex < rightIndex) data[leftIndex++] = data[rightIndex]; //從左邊找到數值>temp的數 while (leftIndex < rightIndex && data[leftIndex] < temp) leftIndex++; //把找到的數放到中間數位置 if (leftIndex < rightIndex) data[rightIndex--] = data[leftIndex]; } //最後將中間數放到真正的中間位置,此時leftIndex=rightIndex data[leftIndex] = temp; //返回中間數下標,以便對左右兩組繼續排序 return leftIndex;}//希爾排序//原理:屬於一種改進的插入排序,將序列按照特定的步長分成若干個子序列,//對各個子序列進行插入排序,然後再按照更小的步長分成若干子序列,對子序列排序,//......最後一步的步長為1,這樣最後一步則“等於”直接插入排序了,此時的序列是//基本有序的,直接插入排序對有序序列的排序效率是很高的void Sort::xiEr(int data[],int size){ int temp; for (int d = size/2; d >=1; d = d/2) { for (int i = d; i < size; i++) { int j = i - d; temp = data[i]; while (j >= 0 && data[j] > temp) { data[j + d] = data[j]; j -= d; } if (j != i - d) data[j + d] = temp; } } print(data,size);}//交換數組中兩個元素void Sort::swap(int data[],int i,int j){ int temp = data[i]; data[i] = data[j]; data[j] = temp;}void Sort::print(int data[],int size){ for (int i = 0; i < size; i++) { cout<<data[i]<<" "; } cout<<endl;}