排序方法之选择排序(c语言实现)

小白学习排序的记录

(三)选则排序

1.简单选则排序

(1)中心代码:二重循环。

(2)具体实现:数组存储,定义一个存最小下标的整数min_index,将数组中的每一个数与所有数依次比较,只要后面的数比第一个数小就把在其下标存在min_index中内层循环结束一次找到一个此时最小的数下标,它存在min_index中,找到后在内层循环外部,将最小值存入此时的i下标位置。(i表示在数组中的几号位)依次找到第几小的数。

代码

代码
void sort(int *nums, int size)
{
    
    for(int i=0;i<size;i++)
    {
        int min_index=i;
        for(int j=i+1;j<size;j++)
        {
            if(nums[j]<nums[min_index])
            {
                min_index=j;
            }
        }
            int temp=nums[i];
            nums[i]=nums[min_index];
            nums[min_index]=temp;
    }
 } 
PS:时间复杂度是O(n*n),空间复杂度是O(1)


2.堆排序

note:其实堆就是把一群数字想象成一个三角堆,就是完全二叉树,有小根堆,大根堆,小根堆就是父节点小于左右孩子,大根堆就是父节点大于左右孩子。

(1)中心代码:循环

(2)具体实现:

1..定义:用数组来存储树,在想象中,数组的下标依次代表其在树中的位置如图

数组下标是从0开始的,已知某一数的下标(i),就可求得其孩子的下标,左孩子为2*i+1,右孩子为2*i+2。

2..实现:一个函数sort用来排小根堆,其实现思路为:给入一个需要排的parent node(leaf nodes 不需要排,没孩子),要父亲和左右孩子中最小的数来做新父亲(parent node),先比较孩子中谁最小,再将最小的孩子与旧父亲比较谁更小,谁小谁做新父亲。注意选取第一个父亲,选下标最大的那个parent node,计算方法,假如一个完全二叉树中有n个结点,最小的,也就是序号最大的那个父亲,为n/2,由于数组从0开始,其在数组中对应的下标为n/2-1。
在main函数中需要不断的调用sort函数排需要排的父亲,直到下标=0时停止循环。

note:排好的数组并不是完全有序的,只能最简便的找到0号位置的数是最大的或是最小的。

代码解释
总代码

#include<stdio.h>
#define N 4
void getsnums(int *nums, int n)
{
    printf("请输入4个数\n"); 
    for(int i=0;i<n;i++)
    {
        scanf("%d", &nums[i]);
    }
 } 
void shownums(int *nums, int n)
{
    for(int i=0;i<n;i++)
    {
        printf("%d ", nums[i]); 
    }
 } 
void sort(int *nums, int n, int m)//堆小根堆的函数 
{
    int data=nums[m];
    for(int j=2*m+1;j<=n;j=j*2+1)
    {
        if(j<n-1&&nums[j]>nums[j+1])j++;
        if(data<=nums[j])break;
        nums[m]=nums[j];
        m=j;
    }
    nums[m]=data;

}
int main()
{
    int f[N];
    getsnums(f, N);//输入树 
    for(int i=N/2-1;i>=0;i--) 
    {
        sort(f, N, i);
    }
    shownums(f, N);
    return 0;
         
 } 

PS:时间复杂度为O(nlogn),空间复杂度为O(n*n)

理解了思想也可以用其他的数据结构实现,可以是链表,就是麻烦。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值