排序算法動圖詳解與代碼實現(選擇排序篇)

1.直接排序
思想:遍歷數組元素,找到其中最小(大)元素,將其放在數組起始位置,再從剩餘數組元素中繼續尋找最小(大)元素,放在已排序序列末尾,重複至整條序列有序。
在這裏插入圖片描述

代碼實現

void select_sort(int* arr,int len)
{
    if(arr == NULL || len<0)
        return ;
    int min = arr[0];
    int min_index = 0;
    for(int i=0;i<len-1;i++)
    {
        min = arr[i];
        min_idex = i;
        for(int j=0;j<len;j++)
        {
            if(min > arr[j])
            {    
                min = arr[j];
                min_index = j;
            }
        }
        //交換最值與當前無序序列首元素位置
        if(i != min_index)
        {
            int temp = arr[i];
            arr[i] = arr[min_index];
            arr[min_index] = temp;
        }
    }
}

優點:一輪比較只需要換一次位置,

缺點:效率慢,不穩定。

2.堆排序
基礎:該排序方法基於“”的數據結構,而“堆”的本質是一個有序排列的完全二叉樹,按照父節點鍵值與子節點鍵值的大小關係分爲大根堆和小根堆。
在這裏插入圖片描述

思想:首先構建大根堆,將該數組(a1,a2……an)命名爲無序區,然後將最大元素(a1)與無序區最後一個元素(an)進行位置互換,得到新的有序區(an)和無序區(a1,a2……an-1),且滿足a[1,2…n-1]<=a[n],然後繼續調整無序區成爲新堆,重複以上算法,得到新的有序區與無序區,直到有序區的元素個數爲n-1,則整個排序過程完成。

在這裏插入圖片描述

代碼實現

#include<stdio.h> 
#include<stdlib.h> 
#include<math.h> 

//堆調整算法
 
void HeapAdjust(int num[],int i,int length) { 
//定義max保存以num[i]爲根的最小堆中最大值的下標,初始值爲i 
int max=i;
//判斷num[i]是否爲根結點 (下標i<=length/2-1的結點都是根節點)
	if(i<=length/2-1) { 
	//判斷num[2*i+1]是否在堆內,若在,判斷其是否大於num[max],若大於,將其下標2*i+1賦予給max 
	if((2*i+1)<length && num[2*i+1]>num[max]) {
	max=2*i+1; 
    }
 //判斷num[2*(i+1)]是否在堆內,若在,判斷其是否大於num[max],若大於,將其下標2*(i+1)賦予給max 
	 if((2*(i+1))<length && num[2*(i+1)]>num[max]) {
 	 max=2*(i+1);
   	}
 //若i不等於max,則說明以num[i]爲根的最小堆中num[max]是最大值,將num[max]與根結點num[i]交換位置
    if(i!=max) { 
    num[i]=num[i]^num[max]; 
    num[max]=num[i]^num[max];
    num[i]=num[i]^num[max]; 
    //交換後,爲防止以num[max]爲根結點的最小堆結構發生變換,再次調用堆調整算法 			
    HeapAdjust(num,max,length);
    }
  }
} 



//堆排序算法 
void HeapSort(int num[],int length) { 
	int i; 
	//找到最後一個非葉子結點,先從最後一個非葉子結點組成的最小堆進行堆調整 		
	for(i=length/2-1;i>=0;i--) //調用調整堆算法將數組從下往上調整爲大根堆 				
	HeapAdjust(num,i,length); 
	for(i=length-1;i>0;i--) {
 	//將數組第一個數和最後一個數換位置 
 	num[i]=num[i]^num[0]; 
 	num[0]=num[i]^num[0]; 
	 num[i]=num[i]^num[0]; 
 	//繼續調用調整堆算法,將剩餘數據組成的堆從上往下調整爲大根堆
  	HeapAdjust(num,0,i);
  	} 
} 

int main() {
 int i; 
 int num[]={8,5,7,12,48,36,4}; 
 HeapSort(num,sizeof(num)/sizeof(int)); 
 for(i=0;i<sizeof(num)/sizeof(int);i++) { 
 	printf("%d\t",num[i]); 
 	} 
 printf("\n");
} 

優點:高效,只需要O(1)的輔助空間。

缺點:不穩定,數據較少時不適合使用。

3.二者複雜度比較
在這裏插入圖片描述

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