睡前攻势——直接插入排序【以及瞎编扑克牌摸牌】

 注:本文相关代码描述参考耿国华教授主编的《数据结构——用C语言描述》(第2版)

        直接插入排序顾名思义是一种十分直接的排序方法,就好像打扑克牌的摸牌阶段,大家逐次摸牌,每摸一张牌将它置于手牌中的合适的位置,便于玩家思考出牌。为了更加贴切表述,本文章将模拟扑克牌摸牌情况。

        算法描述:将第i个记录插入到前面已经排好顺序的记录中(”记录“释义:数据元素的通俗叫法)。即第i个记录的关键字K同前面已经排好序的i-1个关键字依次比较,将所有关键字大于K的记录向后移动一格位置,直到遇见关键字小于或等于K的记录,这时,小于或等于K的记录的后一位是空的,直接将关键字K的记录插入该空位置。完整的直接插入排序是从i = 2开始的。为什么从i = 2开始?i = 0的记录是用于监视哨,i = 1的记录视为我们摸到的第一张牌,没有先前的有序记录进行比较,即将i = 1的记录视作已经排好的序列。

算法代码:

void insSort(Elements e[],int len){
    int i,j;
    for(i= 2;i <= len;i++){ //遍历手牌
        e[0] = e[i];
        j = i - 1;
        while(e[0].key < e[j].key){ //比较
            e[j+1] = e[j];
            j = j - 1;
        }
        e[j + 1] = e[0];
    }
}

        算法的要点:①使用监视哨e[0]临时保存待插入的记录;②从后往前查找应插入的位置;③查找和移动同时进行

        算法分析:1、从空间角度来看,它只需要一个辅助空间e[0]。

                           2、从时间角度来看,主要时间耗费在关键字的比较和元素移动上。

                           ①最好情况:e[i].key>=e[i-1].key,原因是只需要执行一次while循环并且直接插入有序序列,不进行元素移动操作。此时,总的比较次数为n-1次,总的移动次数为2(n-1)【即每次循环中e[0] = e[i]和e[j+1] = e[0]两次】;

                           ②最坏情况:e[i].key<e[1].key,while循环中关键字的比较次数和移动记录次数为i-1。此时,总的比较次数为(n+2)(n-1)/2,总的记录移动次数为:(n+4)(n-1)/2;

算法执行的时间耗费主要取决于数据分布情况,如果待排序记录是随机的,即待排序记录可能出现的各种排列的概率相同,则可以取上述最小值和最大值的平均值,约为n^2/4。因此,直接插入排序的时间复杂度为T(n) = O(n^2),空间复杂度为S(n)=O(1)

扑克牌摸牌程序:

#include<stdio.h>
typedef char* anyType;//一张扑克牌中能够想到的其它属性,比如花色
typedef char* Character;//扑克牌的表面名称属性
typedef int Key;//用于比较扑克牌大小的关键属性
const int MAXSIZE = 100;

//定义扑克牌
typedef struct{
    Key key;
    Character role;
    anyType anything;
}Elements;

//直接插入算法
void insSort(Elements e[],int len){
    int i,j;
    for(i= 2;i <= len;i++){ //遍历手牌
        e[0] = e[i];
        j = i - 1;
        while(e[0].key < e[j].key){ //比较
            e[j+1] = e[j];
            j = j - 1;
        }
        e[j + 1] = e[0];
    }
}

//使用扑克牌关键属性匹配扑克牌表面属性
void cardsMatching(Elements e[],int len){
    for(int i = 1;i <= len;i++){
        switch(e[i].key){
            case 3: e[i].role = "3";break;
            case 4: e[i].role = "4";break;
            case 5: e[i].role = "5";break;
            case 6: e[i].role = "6";break;
            case 7: e[i].role = "7";break;
            case 8: e[i].role = "8";break;
            case 9: e[i].role = "9";break;
            case 10: e[i].role = "10";break;
            case 11: e[i].role = "J";break;
            case 12: e[i].role = "Q";break;
            case 13: e[i].role = "K";break;
            case 14: e[i].role = "A";break;
            case 15: e[i].role = "2";break;
            case 16: e[i].role = "pokerShortJoker";break;
            case 17: e[i].role = "pokerBigToker";break;
            default: printf("wrong!\n");break;
        }
    }
}

//展示手牌
void outPut(Elements e[],int len){
    printf("手牌是:\n");
    for(int k = len;k >= 1;k--){
            printf("\t%s\n",e[k].role);
        }
}
int main(){
    Elements a[MAXSIZE];
    int num,length;
    int i = 1;
    printf("请摸牌:\n");
    while(scanf("%d",&num)){
        if(num < 3 || num > 17){ //本程序的局限性,应当有一个有效数的判断
            printf("错误的摸牌,请重摸牌\n");
            continue;
        }
        a[i++].key = num;
    }
    length = i - 1;
    insSort(a,length);
    cardsMatching(a,length);
    outPut(a,length);
    return 0;
}

结果演示:

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值