書小宅之數據結構——常見7種排序算法的實現(c++)

穩定的排序算法 指不會改變關鍵碼值相同的記錄的相對順序。

一:插入排序

概念:對數組每次多往後遍歷一個元素,在數組有序部分找到該元素對應的位置。
最差時間複雜度: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;
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章