乔治爱啃脚趾 发表于 2023-12-13 19:49:18

直接插入排序

进行直接插入排序的同时统计在排序过程中对关键字的比较次数和移动次数,并分别输出排序前的数据序列和排序后的数据序列及其统计结果。
下面是我写的部分代码,请帮我看看。
#include<stdio.h>
#include <stdlib.h>
#define MAXSIZE 80   //顺序表的最大长度
typedefintKeyType;   // 将关键字类型定义为整型
typedefintInfoType;   // 将其它数据项类型也定义为整型
struct
{        int cpn;      //记录比较次数
        int mvn;   //记录移动次数
} cm;       //分别用来记录三种排序的比较和移动次数,并可将此数组定义为全局变量
typedefstruct{
    KeyType   key;            // 关键字项
    InfoTypeotherinfo;      // 其它数据项
}RedType;                     // 记录类型
typedefstruct{
    RedType   r;   //一般情况将r闲置
    int       length;      // 顺序表长度
}SqList;          //顺序表的类型
void zhijiecharu(SqList &L,int n)
{
        int i,e,j;
        L.r=(RedType)malloc(sizeof(RedType)*MAXSIZE);
        L.length=1;
        for(i=1;i<=n;i++)
        {
                scanf("%d",&L.r.key);
                L.length++;
        }
        for(i=1,j=2;j!=L.length;j++)
        {
                if(L.r.key>L.r.key){
                        L.r.key=L.r.key;
                        while(cm.cpn++,L.r.key>L.r.key)
                        {
                                L.r.key=L.r.key;
                                i--;
                                cm.mvn++;       
                        }
                        L.r=L.r;
                        i=j;
                }
                else
                {
                        i++;
                        cm.cpn++;
                }
        }
}

FishC 发表于 2023-12-13 19:49:56

你的代码有几个问题需要修改:

1. 在定义 `struct` 结构体时,结构体名字缺少了,应该是类似 `struct Counter{...}` 的形式。
2. 定义结构体变量 `cm` 时缺少了结构体名字,应该是 `Counter cm;`。
3. 为了记录比较次数和移动次数,需要在每次比较或移动操作之后,将 `cm.cpn` 或 `cm.mvn` 加一。
4. 在 `zhijiecharu` 函数中,对 `L.r` 进行了动态内存分配,但是没有进行释放。应该在函数结束前加上 `free(L.r);`。

除了上述问题,你的代码基本实现了直接插入排序,并且统计了比较次数和移动次数。

下面是修复后的代码:

#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 80   //顺序表的最大长度
typedef int KeyType;   // 将关键字类型定义为整型
typedef int InfoType;   // 将其它数据项类型也定义为整型

struct Counter {
    int cpn;      //记录比较次数
    int mvn;   //记录移动次数
};       //分别用来记录三种排序的比较和移动次数,并可将此数组定义为全局变量

typedef struct {
    KeyType key;            // 关键字项
    InfoType otherinfo;      // 其它数据项
} RedType;                     // 记录类型

typedef struct {
    RedType *r;   //一般情况将r闲置
    int length;      // 顺序表长度
} SqList;          //顺序表的类型

void zhijiecharu(SqList &L, int n)
{
    int i, j;
    L.r = (RedType*)malloc(sizeof(RedType) * MAXSIZE);
    L.length = 0;
   
    for (i = 1; i <= n; i++) {
      scanf("%d", &(L.r.key));
    }
   
    Counter cm = {0, 0}; // 初始化比较次数和移动次数
   
    for (i = 2; i <= n; i++) {
      if (L.r.key < L.r.key) {
            L.r = L.r; // 复制为哨兵
            L.r = L.r; // 后移一个元素
            cm.mvn++;
            
            for (j = i-2; L.r.key < L.r.key; --j) {
                L.r = L.r;
                cm.mvn++;
                cm.cpn++;
            }
            
            L.r = L.r; // 插入到正确位置
            cm.mvn++;
      } else {
            cm.cpn++;
      }
    }
   
    printf("排序前的数据序列:");
    for (i = 1; i <= n; i++) {
      printf("%d ", L.r.key);
    }
    printf("\n");
   
    printf("排序后的数据序列:");
    for (i = 1; i <= n; i++) {
      printf("%d ", L.r.key);
    }
    printf("\n");
   
    printf("比较次数:%d\n", cm.cpn);
    printf("移动次数:%d\n", cm.mvn);
   
    free(L.r);
}

希望对你有帮助!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

sfqxx 发表于 2023-12-13 19:57:49

你的代码有一些小错误,但是你的整体思路是对的。将关键字进行比较,移动到合适的位置。

根据你的代码,我帮你调整一下,核心部分不变。

#include<stdio.h>
#include <stdlib.h>

#define MAXSIZE 80// 顺序表的最大长度

typedef int KeyType; // 将关键字类型定义为整型
typedef int InfoType; // 将其它数据项类型定义为整型

struct {
    int cpn;//记录比较次数
    int mvn;//记录移动次数
} cm;//分别记录三种排序的比较和移动次数,全局变量

typedef struct {
    KeyTypekey;// 关键字项
    InfoType otherinfo; // 其它数据项
} RedType;//记录类型

typedef struct {
    RedTyper; // r闲置
    int length;// 顺序表长度
} SqList; //顺序表的类型

void zhijiecharu(SqList &L)
{
    int i,j;
    for(i=2; i<=L.length; i++)
    {
      if(L.r.key < L.r.key){
            L.r = L.r;
            L.r = L.r;
            j = i-2;
            cm.cpn++;
            while(j>0 && L.r.key<L.r.key)
            {
                L.r = L.r;
                j--;
                cm.mvn++;         
            }
            L.r=L.r;
      }
    }
}

int main()
{
    SqList L;
    int n;
    int i;
    printf("请输入元素个数:\n");
    scanf("%d", &n);
    L.length = n;
    printf("请输入需要排序的数据:\n");
    for(i=1; i<=n; i++)
    {
      scanf("%d", &L.r.key);
    }
    printf("排序前的数据序列为:\n");
    for(i=1; i<=n; i++)
    {
      printf("%d ", L.r.key);
    }
    printf("\n");
    zhijiecharu(L);
    printf("排序后的数据序列为:\n");
    for(i=1; i<=n; i++)
    {
      printf("%d ", L.r.key);
    }
    printf("\n关键字的比较次数:%d\n", cm.cpn);
    printf("关键字的移动次数:%d\n", cm.mvn);
    return 0;
}


这个版本的代码我在主函数里增加了从用户那边获取数据的交互,同时在排序前后都打印了数组的内容,以便于查看排序效果。

不需要提示语可以去掉。

求最佳答案{:10_254:}

sfqxx 发表于 2023-12-13 20:06:32

6

Exusiaii 发表于 2023-12-14 14:12:07

@FishC 用c语言回答下述问题
假设以一个带权有向图表示某一区域的公交线路网,图中顶点代表一些区域中的重要场所,弧代表已有的公交线路,弧上的权表示该线路上的票价(或搭乘所需时间),试设计一个交通指南系统,指导前来咨询者以最低的票价或最少的时间从区域中的某一场所到达另一场所。
2)实验要求:利用Dijkstra算法求最低的票价
3) 实现提示:
该问题可以归结为一个求带权有向图中顶点间最短路径的问题。
建立以票价为权的有向图,再利用Dijkstra算法求最短路径及其路径长度。
页: [1]
查看完整版本: 直接插入排序