排序算法动图详解与代码实现(选择排序篇)

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.二者复杂度比较
在这里插入图片描述

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