选择排序(简单选择、堆排序)

本文介绍了两种常见的排序算法:简单选择排序和堆排序。对于简单选择排序,分别展示了适用于顺序表和链表的实现方式。而在堆排序部分,详细阐述了大根堆和小根堆的构建过程,并提供了相应的代码实现。通过这些排序算法,读者可以更好地理解和应用数据结构与算法。
摘要由CSDN通过智能技术生成

 1、简单选择排序(顺序表、链表)

/**
 *
 * 选择排序:
 * 1、简单选择排序
 * 2、堆排序
 *
 * ①算法思想
 *
 * ②算法设计
 *
 */

#include <stdio.h>
#include <iostream>
#include <cstdio>
#include <malloc.h>
#include <cstdlib>
#define MaxSize 20
#define INF 999999


//选择排序
//1、简单选择排序---顺序表
void SelectSort(int arr[],int n){
    int minIndex,temp;
    for (int i = 0; i < n - 1; ++i) {//执行 n-1 轮就行,因为 n-1 个元素确定了之后,最后一个元素就确定了
        minIndex = i;//还没有排序的元素里面默认最小的元素处于还没有排序的这些元素的第一个位置
        for (int j = i + 1; j < n; ++j) {
            if(arr[j] < arr[minIndex])
                minIndex = j;
        }
        if(minIndex != i){//减少不必要的交换
            temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
    }
}
//1、简单选择排序---链表(带头结点)
typedef struct LNode{
    int data;
    struct LNode *next;
}LNode,*LinkList;
void SelectSort(LinkList &L){
    LinkList S = (LinkList)malloc(sizeof(LNode));//额外定义了一个头结点,借助S这个头排出有序的之后再给L然后S被释放掉
    LinkList r = S,pre,p,minPre,minP;
    while(L -> next != NULL){
        pre = L,p = L -> next;
        minPre = pre,minP = p;
        while(p != NULL){
            if(p -> data < minP -> data){
                minPre = pre;
                minP = p;
            }
            pre = p;
            p = p -> next;
        }//找到了最小值
        minPre -> next = minP -> next;//把这一轮的最小值删除,方便下一轮查找最小值
        r -> next = minP;
        r = minP;
    }
    r -> next = NULL;
    L -> next = S -> next;
    free(S);
}

 2、堆排序(大根堆---升序、小根堆---降序)

//2、堆排序
//①大根堆:升序
//第一步:调整函数:将以 k 为根的子树调整为大根堆
void HeadAdjust_Max(int arr[],int k,int len){
    arr[0] = arr[k];//哨兵
    for (int i = 2 * k; i <= len ; i *= 2) {//i=2*k是k这个节点的左孩子
        if(i < len && arr[i] < arr[i + 1])//i<len保证了k这个节点有右孩子
            i++;
        if(arr[0] >= arr[i])
            break;
        else{
            arr[k] = arr[i];
            k = i;
        }
    }
    arr[k] = arr[0];
}
//第二步:建立大根堆
void BuildMaxHeap(int arr[],int len){
    for(int i = len / 2; i >= 1; --i){
        HeadAdjust_Max(arr,i,len);
    }
}
//第三步:堆排序
void HeapSort(int arr[],int len){
    int temp;
    BuildMaxHeap(arr,len);
    for (int i = len; i > 1 ; --i) {
        temp = arr[i];
        arr[i] = arr[1];
        arr[1] = temp;
        HeadAdjust_Max(arr,1,i - 1);
    }
}


//②小根堆:降序
//第一步:调整函数:将以 k 为根的子树调整为小根堆
void HeadAdjust_Min(int arr[],int k,int len){
    arr[0] = arr[k];//哨兵
    for (int i = 2 * k; i <= len ; i *= 2) {//i=2*k是k这个节点的左孩子
        if(i < len && arr[i] > arr[i + 1])//i<len保证了k这个节点有右孩子
            i++;
        if(arr[0] <= arr[i])
            break;
        else{
            arr[k] = arr[i];
            k = i;
        }
    }
    arr[k] = arr[0];
}
//第二步:建立小根堆
void BuildMinHeap(int arr[],int len){
    for(int i = len / 2; i >= 1; --i){
        HeadAdjust_Min(arr,i,len);
    }
}
//第三步:堆排序
void HeapSort(int arr[],int len){
    int temp;
    BuildMaxHeap(arr,len);
    for (int i = len; i > 1 ; --i) {
        temp = arr[i];
        arr[i] = arr[1];
        arr[1] = temp;
        HeadAdjust_Max(arr,1,i - 1);
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值