内部排序

排序算法的分类:
根据文件记录的存放位置:

  • 内部排序:排序过程中将全部记录放在内存中处理
  • 外部排序:排序过程中需在内外存之间交换信息

内部排序算法梳理

①插入排序:
直接插入排序(基于顺序查找)
折半插入排序(基于折半查找)
表插入排序(基于链表存储)
希尔排序(基于逐趟缩小增量)
②交换排序:
冒泡排序
快速排序
③选择排序:
简单选择排序
树形选择排序(锦标赛排序)
堆排序
④归并排序:
两路归并排序
⑤基数排序(分配排序):
基数排序


各种内部排序方法的比较

排序算法比较

数据存储结构

约定:顺序存储,关键字类型为int型
有两种方式:
1. 数组存数据(这是我的代码版本)
2. 用到结构体(课件ppt上的版本)

#define MaxSize 20
typedef int KeyType
typedef struct
{
    KeyType key;//存储关键字
    InfoType otherinfo;//其余信息
}RedType;

typedef struct 
{
    RedType a[MaxSize+1];//a[0]闲置或作哨兵
    int length;//关键字数目
}SqList;

各排序算法详解

main函数中初始化数组以及swap函数定义

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 12
void swap(int &a, int &b);
void Insert(int a[], int n);

int main()
{
    int array[MAXSIZE+1];//从下标1开始存
    int i;
    printf("Please input %d numbers.\n", MAXSIZE);
    for (i = 1; i < MAXSIZE + 1; i++)//读入MaxSize个关键字
    {
        scanf_s("%d", &array[i]);
    }
    printf("Input successfully!\n");
    Insert(array, MAXSIZE);//根据不同排序算法调用的函数有所不同
    printf("The result is:\n");//排好序了,下面打印
    for (i = 1; i < MAXSIZE + 1; i++)
    {
        printf("%d ", array[i]);
    }
    system("pause");
    return 0;

}

void swap(int &a, int &b)//swap函数定义
{
    int temp;
    temp = a;
    a = b;
    b = temp;
}

1.插入排序

  • 直接插入排序

思路:
一次比到底,从第二个关键字开始,直到最后一个关键字,首先每个关键字与它前面的关键字比,看是否满足升序或降序,若不满足则swap且j往前挪一个,直到比较到第一个或者满足升序或降序。
需注意的是,插入排序就是一个个跟前面的比较,而其前面的序列已经排好队了。
和冒泡排序的差别是,直接插入一次比到底。

代码实现

void Direct_Insert(int a[], int n)//传入数组首地址(即数组名)和关键字个数即MaxSize
{
    int i,j;//存储下标的变量
    for(i=2;i<=n;i++)//i控制的是下标
    {
         j=i;
         while(j>1&&a[j]<a[j-1])//如果不是升序 则swap
         {
             swap(a[j],a[j-1]);
             j--;
         }
    }
}
  • 折半插入排序
    即把直接插入排序的顺序查找操作改为折半查找,以减少关键字比较次数,效率更高。

  • 2-路插入排序

  • 希尔排序
    由于直接插入排序在待排序列基本有序和待排记录数量少时,效率高,故希尔排序就是从宏观上将待排序列调整到基本有序,再使用直接插入排序将其全部排序。

而希尔排序的思路是,采用增量递减的方法,先设一个增量d,然后按增量d进行分组,每组之中采用直接插入排序,排完后减小增量d, 比如将其调整为原来的1/2,再在每组中采用直接插入排序,直到增量d为1,即只有一组,且所有关键词都在这一组中,进行最后的直接插入排序。(增量d的设定是关键)

交换排序

  • 冒泡排序

算法思路:从第一位开始,临近的数两两比较,按照升序或降序进行交换,这样一趟过去后,最大或最小的数被放到最后一位,然后再从头开始两两比较,直到倒数第二位时结束,以此类推。

Notes: 冒泡排序和直接插入排序的不同:
直接插入排序是确定待插入的数之前的序列是已经排好的,只需一个个和前面的比,找到合适的位置,插入;而冒泡排序是从头开始向后两两比较,和他比较的是否满足升序或降序的条件,它都要比到最后一个,根据它是第几趟排序来判断,至多进行n-1趟

代码实现:

#define TRUE 1
#define FALSE 0
void BubbleSort(int a[],int n)
{
    int Sorted;
    int i,j;
    for(i=0;i<n-1&&(!Sorted);i++)//因为下面要n-i故i从0开始,且至多进行n-1趟,故i<n-1
    {
        Sorted=TRUE;
        for(j=1;j<n-i;j++)//已排好的后面i个不用比较
        {
            if(a[j]>a[j+1])//如果不满足升序
            {
                swap(a[j],a[j+1]);
                Sorted=FALSE;
            }
        }
    }
}
//Sorted作用,我认为是,当外循环第i趟时,内部无操作,则后面第i+1直到n-1趟时,内部都无操作,也就是当内部无操作时,这时已经提前排好序了,循环可以跳出了。
  • 快速排序

选择排序

  • 简单选择排序

算法思路:
从第一个数开始,依次往后遍历到最后一个数,找到最大的数的下标,swap第一个数和最大的数;再从第二个数开始往后遍历,直到到了最后一个数。

代码实现

void Select_Sort(int a[], int n)
{
    int i, j, pos;//pos是当前要比较的元素下标
    for (i = 1; i <= MAXSIZE; i++)//找当前趟最大的数
    {
        pos = i;
        for (j = i+1; j <= MAXSIZE; j++)
        {
            if (a[j] > a[pos])
            {
                pos = j;

            }
        }//循环跳出后pos存储当前最大元素的下标
        swap(a[i], a[pos]);

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值