排序演算法(直接插入、氣泡排序、選擇排序、快速排序、希爾排序、堆排序、歸併排序)
阿新 • • 發佈:2018-11-07
main函式
int main()
{
int data[] = {1,2,6,3,4,7,7,9,8,5};
//bubble_sort(data,10);
//select_sort(data,10);
Insert_Sort(data,10);
for(int i = 0; i < 10; i++)
cout << data[i] <<" ";
cout <<endl;
return 0;
}
直接插入排序 O(n^2) 穩定
//插入排序 void Insert_Sort(int *pData, int Count) { int iTmp ; int iPos; for(int i = 1; i < Count; i++) { iTmp = pData[i]; iPos = i-1; while(iPos>=0 && pData[iPos]>iTmp) { pData[iPos+1] = pData[iPos]; iPos--; } pData[iPos+1] = iTmp; } return ; }
氣泡排序 O(n^2) 穩定
//*** 氣泡排序 **// void bubble_sort(int *pData, int count) { for(int i = 0; i < count; i++) { for(int j = count-1; j >= i; j--) { if(pData[j] < pData[j-1]) { int tmp; tmp = pData[j]; pData[j] = pData[j-1]; pData[j-1] = tmp; } } } }
選擇排序 O(n^2) 不穩定
//***選擇排序***/// void select_sort(int *pData, int count) { int tmp; int iPos; for(int i = 0; i < count-1; i++ ) { tmp = pData[i]; iPos = i; for(int j = i+1; j < count; j++) { if(pData[j] < tmp) { tmp = pData[j]; iPos = j; } } pData[iPos] = pData[i]; pData[i] = tmp; } }
快速排序 O(nlog(n)) 不穩定
//快速排序 遞迴
void Quick_Sort(int *pData, int low, int high)
{
int i = low;
int j = high;
int x = pData[i];
if(low > high)
return;
while( i < j )
{
while( i < j && pData[j] >= x)
j--;
pData[i] = pData[j];
while( i < j && pData[i] <= x)
i++;
pData[j] = pData[i];
}
pData[i] = x;
Quick_Sort(pData, low, i-1);
Quick_Sort(pData, i+1, high);
}
//快排 非遞迴
int partion(int* pData,int low,int high)
{
int tmp = pData[low];
while(low < high)
{
while(low < high && pData[high] > tmp)
high--;
pData[low] = pData[high];
while(low < high && pData[low] < tmp)
low++;
pData[high] = pData[low];
}
pData[low] = tmp;
return low;
}
void quickSort(int* pData,int low,int high)
{
stack<int> S;
int k,i,j;
if(low > high)
return;
if(low < high)
{
S.push(low);
S.push(high);
while(!S.empty())
{
//不空時,依次把左邊的和右邊的入棧
j = S.top();
S.pop();
i=S.top();
S.pop();
k=partion(pData,i,j); //彈出來後進行比較
/*再次將左右兩邊分別入棧*/
if(i < k-1)
{
S.push(i);
S.push(k-1);
}
if(k+1 < j)
{
S.push(k+1);
S.push(j);
}
}
}
}
希爾排序 O(nlog(n)) 不穩定
根據插入排序改,換步長即可
void Insert_Sort(int *pData, int Count)
{
int iTmp ;
int iPos;
int gap = Count;
do{
gap = gap / 3 + 1; //後面一定要有+1 ,不然無法保證最後的間隔為1
for(int i = gap - 1 ; i < Count; i++)
{
iTmp = pData[i];
iPos = i-gap;
while( iPos >= 0 && pData[iPos] > iTmp )
{
pData[iPos+gap] = pData[iPos];
iPos -= gap;
}
pData[iPos+gap] = iTmp;
}
}while(gap > 1);
return ;
}
堆排序 O(nlog(n)) 不穩定
//構造最大堆
void MaxHeapFixDown(int a[], int i, int n){
int j = 2*i+1; //左葉子
int temp = a[i]; //根節點
while(j < n){ //一個子樹的判斷
if(j+1 < n && a[j] < a[j+1]) // 左節點小於右節點,就繼續往下走
++j;
if(temp > a[j]) //當根節點大於最大的左節點時就跳出來
break;
else{
a[i] = a[j];//否則就把大的交換
i=j; //j賦給i
j=2*i+1; //j到最右邊
}
}
a[i]=temp; //根與最大的節點交換
}
//堆排序
void Head(int a[], int n){
for(int i= n/2-1;i >=0;i--)
MaxHeapFixDown(a,i,n); //找到最大的數了
for(int i=n-1;i>=1;i--){
swap(a[i],a[0]); //交換最大的數與葉節點
MaxHeapFixDown(a,0,i);
}
}
歸併排序 O(nlog(n)) 穩定
//歸併排序
//將陣列分治為兩個有序的陣列,然後傳給Merge
void Merge_Sort(int *pData, int Count)
{
if(Count > 1)
{
int *list1 = pData;
int list1_size = Count / 2;
int *list2 = pData + list1_size;
int list2_size = Count - list1_size;
Merge_Sort(list1,list1_size);
Merge_Sort(list2,list2_size);
Merge(list1,list1_size,list2,list2_size);
}
return;
}
//Merge將兩個有序的數組合並
void Merge(int *list1, int list1_size, int *list2, int list2_size)
{
int tmp[list1_size+list2_size];
int i = 0;
int j = 0;
int k = 0;
while (i < list1_size && j < list2_size )
{
if( list1[i] < list2[j])
tmp[k++] = list1[i++];
else
tmp[k++] = list2[j++];
}
while (i < list1_size)
tmp[k++] = list1[i++];
while (j < list2_size)
tmp[k++] = list2[j++];
int m = 0;
for(; m < (list1_size + list2_size);m++)
list1[m] = tmp[m];
return;
}