穩定的排序算法
指不會改變關鍵碼值相同的記錄的相對順序。
一:插入排序
概念:對數組每次多往後遍歷一個元素,在數組有序部分找到該元素對應的位置。
最差時間複雜度:O(n2)
是否穩定:穩定
#include<iostream>
#include <algorithm>
using namespace std;
void insertSort(int array[], int n)
{
int i, j;
for (i = 1; i < n; i++){
for(int k=0;k<n;k++)
cout<<array[k]<<" ";
cout<<endl;
for (j = i -1; j >= 0 && array[j] > array[j + 1]; j--)
swap(array[j], array[j + 1]);
}
cout<<endl;
}
int main(){
int array[] = {0,42,20,17,13,28,14,23,15,77};
insertSort(array,sizeof(array)/sizeof(array[0]));
cout<<"排序結果 : "<<endl;
for(int i=0;i<sizeof(array)/sizeof(int);i++)
cout<<array[i]<<" ";
cout<<endl;
return 0;
}
二:冒泡排序
概念:比較相鄰的關鍵碼,低序號的關鍵碼值大於高序號的關鍵碼值。
最差時間複雜度:O(n2)
是否穩定:穩定
#include<iostream>
#include <algorithm>
using namespace std;
void bubbleSort(int array[], int n)
{
int i, j;
for (i = 0; i < n-1; i++){
for(int k=0;k<n;k++)
cout<<array[k]<<" ";
cout<<endl;
for (j = n -1; j>i; j--)
if(array[j] > array[j-1])
swap(array[j],array[j-1]);
}
cout<<endl;
}
int main(){
int array[] = {0,42,20,17,13,28,14,23,15,77};
bubbleSort(array,sizeof(array)/sizeof(array[0]));
cout<<"排序結果 : "<<endl;
for(int i=0;i<sizeof(array)/sizeof(int);i++)
cout<<array[i]<<" ";
cout<<endl;
return 0;
}
三:選擇排序
概念:每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,直到全部待排序的數據元素排完。
最差時間複雜度:O(n2)
是否穩定:不穩定
#include<iostream>
#include <algorithm>
using namespace std;
void selectSort(int array[], int n)
{
int i, j;
for (i = 0; i < n-1; i++){
for(int k=0;k<n;k++)
cout<<array[k]<<" ";
cout<<endl;
int lowindex = i;
for (j = n -1; j>i; j--)
if(array[j] > array[lowindex])
lowindex = j;
swap(array[i],array[lowindex]);
}
cout<<endl;
}
int main(){
int array[] = {0,42,20,17,13,28,14,23,15,77};
selectSort(array,sizeof(array)/sizeof(array[0]));
cout<<"排序結果 : "<<endl;
for(int i=0;i<sizeof(array)/sizeof(int);i++)
cout<<array[i]<<" ";
cout<<endl;
return 0;
}
四:Shell排序
概念:又稱作縮小增量排序,使待排序列基本有序,再插入排序。
最差時間複雜度:O(n2)
是否穩定:不穩定
#include<iostream>
#include <algorithm>
using namespace std;
void inssort(int array[], int n, int incr)
{
for (int i = incr; i < n; i += incr){
for(int k=0;k<n;k++)
cout<<array[k]<<" ";
cout<<endl;
for(int j=i; (j >= incr) && (array[j] > array[j-incr]); j -= incr)
swap(array[j],array[j-incr]);
}
}
void shellSort(int array[], int n)
{
int i, j;
for (int i = n/2; i > 2; i /= 2){
for(int j=0; j < i; j++)
inssort(&array[j] , n-j, i);
}
inssort(array , n, 1);
cout<<endl;
}
int main(){
int array[] = {0,42,20,17,13,28,14,23,15,77};
shellSort(array,sizeof(array)/sizeof(array[0]));
cout<<"排序結果 : "<<endl;
for(int i=0;i<sizeof(array)/sizeof(int);i++)
cout<<array[i]<<" ";
cout<<endl;
return 0;
}
五:歸併排序
概念:迭代對排好序的兩部分數據進行歸併。
最差時間複雜度:O(nlogn)
是否穩定:穩定
#include<stdio.h>
#include <iostream>
using namespace std;
void merge(int array[],int temp[],int l,int r,int rightend) {
int t=l;
int start = l;
int leftend=r-1;
while(l<=leftend && r<=rightend){
if(array[l]<=array[r])
temp[t++]=array[l++];
else
temp[t++]=array[r++];
}
while(l<=leftend) temp[t++]=array[l++];
while(r<=rightend) temp[t++]=array[r++];
for(int i=start;i<t;i++)
array[i]=temp[i];
}
void sort(int array[],int temp[],int l, int r) {
int center;
if(l<r) {
center=(l+r)/2;
sort(array,temp,l,center);
sort(array,temp,center+1,r);
merge(array,temp,l,center+1,r);
}
}
void mergeSort(int array[],int n) {
int temp[100];
sort(array,temp,0,n-1);
}
int main(){
int array[] = {0,42,20,17,13,28,14,23,15,77};
int n=sizeof(array)/sizeof(int);
cout<<"原來的數組 : "<<endl;
for(int i=0;i<n;i++)
cout<<array[i]<<" ";
cout<<endl<<endl;
mergeSort(array,n);
cout<<"排序結果 : "<<endl;
for(int i=0;i<n;i++)
cout<<array[i]<<" ";
cout<<endl;
}
六:快速排序
概念:迭代分類到軸值兩側。
最差時間複雜度:O(nlogn)
是否穩定:不穩定
#include<iostream>
using namespace std;
int getMid(int array[],int left,int right)
{
int mid = left + ((right - left)>>1);
if(array[left] <= array[right])
{
if(array[mid] < array[left])
return left;
else if(array[mid] > array[right])
return right;
else
return mid;
}
else
{
if(array[mid] < array[right])
return right;
else if(array[mid] > array[left])
return left;
else
return mid;
}
}
int PartSort3(int array[],int left,int right)
{
int mid = getMid(array,left,right);
swap(array[mid],array[right]);
if(left < right){
int key = array[right];
int cur = left;
int pre = left - 1;
while(cur < right)
{
while(array[cur] < key && ++pre != cur)
{
swap(array[cur],array[pre]);
}
++cur;
}
swap(array[++pre],array[right]);
return pre;
}
return -1;
}
void QuickSort(int array[],int left,int right)
{
if(left >= right)
return;
int index = PartSort3(array,left,right);
QuickSort(array,left,index-1);
QuickSort(array,index+1,right);
}
int main()
{
int array[] = {0,42,20,17,13,28,14,23,15,77};
QuickSort(array,0,sizeof(array)/sizeof(array[0]) -1);
cout<<"排序結果 : "<<endl;
for(int i=0;i<sizeof(array)/sizeof(int);i++)
cout<<array[i]<<" ";
cout<<endl;
}
七:堆排序
概念:是指利用堆積樹(堆)設計選擇排序。堆分爲大根堆和小根堆,是完全二叉樹。大根堆的要求是每個節點的值都不大於其父節點的值,因此最大的值一定在堆頂【用於非降序排序】
最差時間複雜度:O(nlogn)
是否穩定:不穩定
小根堆
:非升序
#include<iostream>
using namespace std;
void AdjustDown(int arr[], int i, int n)
{
int j = i * 2 + 1;//子節點
while (j<n)
{
if (j+1<n && arr[j] > arr[j + 1])//子節點中找較小的
j++;
if (arr[i] < arr[j])
break;
swap(arr[i],arr[j]);
i = j;
j = i * 2 + 1;
}
}
void MakeHeap(int arr[], int n)//建堆
{
int i = 0;
for (i = n / 2 - 1; i >= 0; i--)//((n-1)*2)+1 =n/2-1
AdjustDown(arr, i, n);
}
void HeapSort(int arr[],int len)
{
int i = 0;
MakeHeap(arr, len);
cout<<"排序過程 : "<<endl;
for (i = len - 1; i >= 0; i--)
{
for(int k=0;k<len;k++)
cout<<arr[k]<<" ";
cout<<endl;
swap(arr[i], arr[0]);
AdjustDown(arr, 0, i);
}
}
int main(){
int array[] = {0,42,20,17,13,28,14,23,15,77};
int n = sizeof(array)/sizeof(int);
HeapSort(array,n);
cout<<"排序結果 : "<<endl;
for(int i=0;i<sizeof(array)/sizeof(int);i++)
cout<<array[i]<<" ";
cout<<endl;
}
大根堆
:非降序
#include<iostream>
using namespace std;
void AdjustDown(int arr[], int i, int n)
{
int j = i * 2 + 1;//子節點
while (j<n)
{
if (j+1<n && arr[j] < arr[j + 1])//子節點中找較小的
j++;
if (arr[i] > arr[j])
break;
swap(arr[i],arr[j]);
i = j;
j = i * 2 + 1;
}
}
void MakeHeap(int arr[], int n)//建堆
{
int i = 0;
for (i = n / 2 - 1; i >= 0; i--)//((n-1)*2)+1 =n/2-1
AdjustDown(arr, i, n);
}
void HeapSort(int arr[],int len)
{
int i = 0;
MakeHeap(arr, len);
cout<<"排序過程 : "<<endl;
for (i = len - 1; i >= 0; i--)
{
for(int k=0;k<len;k++)
cout<<arr[k]<<" ";
cout<<endl;
swap(arr[i], arr[0]);
AdjustDown(arr, 0, i);
}
}
int main(){
int array[] = {0,42,20,17,13,28,14,23,15,77};
int n = sizeof(array)/sizeof(int);
HeapSort(array,n);
cout<<"排序結果 : "<<endl;
for(int i=0;i<sizeof(array)/sizeof(int);i++)
cout<<array[i]<<" ";
cout<<endl;
}