数据结构与算法分析(C语言)的1.1节的代码实现

a设有N个数,要确定其中第k个最大者,(我实现的是第k个最小者),也就是选择问题,C语言实现:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define TOTAL_NUMBER 100000
#define KTH 50

//函数声明
void displayArray(int *data, int length, const char * preDisplay);

/*
* 产生指定数量的随机数
*/
int* generateIntergerArray(int totalNumber)
{
  int* numberArray = (int *)malloc(sizeof(int)*totalNumber);
  int i = 0;
  for(i = 0; i<totalNumber; i++)
  {
    *(numberArray + i) = rand();
  }
  return numberArray;
}

/*
* 冒泡法对随机数组进行排序,从小到大
*/
int * bubleSort(int * data,int length)
{
  int i = 0;
  int j = 0;
  // 变量i用来控制比较的范围,每次少比较右面的一个数,也就是最大的那个数
  for(i = 0; i < length - 1; i++) //i:= 0,1,2...,length -2,一共length-1次比较
  {
    // 变量j用来对数组中的数逐个比较,j为索引
    // 每次比较从第2个开始,到第length - i - 1个结束。当i=0时,data[length-1]就是最后一个数
    for(j = 1; j <= length - i - 1; j++)
    {
      int temp = 0;
      // 如果前一个数大于后一个数,那么这两个数互换。
      if(*(data + j - 1) > *(data + j))
      {
        temp = *(data + j - 1);
        *(data + j - 1) = *(data + j);
        *(data + j) = temp;
      }
    }
    // displayArray(data,length,"-------->");
  }
  return data;
}

/*
* 输出数组中的数
*/
void displayArray(int *data, int length,const char * preDisplay)
{
  printf(preDisplay);
  int i = 0;
  for(i = 0;i < length; i++)
  {
    printf("%d,",*(data+i));
  }
  printf("\n\n");
}

/*
* 显示数组中的第k个数
*/
void displayKthElement(int *data, int k,const char * preDisplay)
{
  printf(preDisplay);
  printf("%d\n\n",*(data + k - 1));
}

/*
* 使用插入法,寻找第k个大的数
*/
int insertAlgorithm(int * data,int length, int kth)
{
  assert(length >= kth);

  // 建立长度为k的数组
  int* kLengthArray = (int*)malloc(sizeof(int)*kth);

  //将data中的前k个数读入kLengthArray中
  int i = 0;
  for(i = 0; i < kth; i++)
  {
    *(kLengthArray + i) = *(data + i);
  }

  // 使用冒泡法对kLengthArray进行排序
  kLengthArray = bubleSort(kLengthArray, kth);
  // displayArray(kLengthArray,kth,"the fist kLengthArray is: \n");
  // 对剩下的数据进行插入
  int count = kth;       // 从第kth+1个数开始进行插入
  int index = kth - 1;   // 从右往左插入,即从第kth个数开始插入
  for(count = kth; count <= length - 1; count++) // 使用第count个数进行比较,然后插入
  {
    // 得到插入的数在kLengthArray中的位置 index
    for(index = kth - 1; index >= -1; index--)
    {
      if (*(data + count) > *(kLengthArray + index))
      {
        break;
      }
    }

    // 如果index不能维持原值,那么存在一个数在kLengthArray的数的中间,需要进行插入操作
    if (index != kth - 1)
    {
      int i = 0;
      for(i = 0; i < kth - index - 2; i++)
      {
        *(kLengthArray + kth - i - 1) = *(kLengthArray + kth - i - 2);
      }
      *(kLengthArray + index + 1) = *(data + count);
    }
  }
  // displayArray(kLengthArray,kth,"the final kLengthArray is: \n");
  return *(kLengthArray + kth - 1);
}


int main()
{
  int* numbers;
  numbers = generateIntergerArray(TOTAL_NUMBER);
  // displayArray(numbers, TOTAL_NUMBER, "random number generated is:\n");

  // 使用冒泡法得到第k个大的数
  int * numbersForBuble = (int*)malloc(sizeof(int)*TOTAL_NUMBER);
  numbersForBuble = bubleSort(numbers,TOTAL_NUMBER);
  displayKthElement(numbersForBuble,KTH,"the k-th element computed by buble algorithm is: ");
  // displayArray(numbersForBuble, TOTAL_NUMBER, "sorted number using buble algorithm is:\n");

  // 使用插入法得到第k个大的数
  int kthNumber = insertAlgorithm(numbers,TOTAL_NUMBER,KTH);
  printf("the k-th number computed by insert algorithm is: %d\n",kthNumber);

  return 0;
}

实验结果,当数据量比较大时(TOTAL_NUMBER比较大),而KTH比较小时,显然时使用插入法的效率更高。


我在上面的程序中加入了计时功能,代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<time.h>
#define TOTAL_NUMBER 500000
#define KTH (TOTAL_NUMBER/2)

//函数声明
void displayArray(int *data, int length, const char * preDisplay);

/*
* 产生指定数量的随机数
*/
int* generateIntergerArray(int totalNumber)
{
  int* numberArray = (int *)malloc(sizeof(int)*totalNumber);
  int i = 0;
  for(i = 0; i<totalNumber; i++)
  {
    *(numberArray + i) = rand();
  }
  return numberArray;
}

/*
* 冒泡法对随机数组进行排序,从小到大
*/
int * bubleSort(int * data,int length)
{
  int i = 0;
  int j = 0;
  // 变量i用来控制比较的范围,每次少比较右面的一个数,也就是最大的那个数
  for(i = 0; i < length - 1; i++) //i:= 0,1,2...,length -2,一共length-1次比较
  {
    // 变量j用来对数组中的数逐个比较,j为索引
    // 每次比较从第2个开始,到第length - i - 1个结束。当i=0时,data[length-1]就是最后一个数
    for(j = 1; j <= length - i - 1; j++)
    {
      int temp = 0;
      // 如果前一个数大于后一个数,那么这两个数互换。
      if(*(data + j - 1) > *(data + j))
      {
        temp = *(data + j - 1);
        *(data + j - 1) = *(data + j);
        *(data + j) = temp;
      }
    }
    // displayArray(data,length,"-------->");
  }
  return data;
}

/*
* 输出数组中的数
*/
void displayArray(int *data, int length,const char * preDisplay)
{
  printf(preDisplay);
  int i = 0;
  for(i = 0;i < length; i++)
  {
    printf("%d,",*(data+i));
  }
  printf("\n\n");
}

/*
* 显示数组中的第k个数
*/
void displayKthElement(int *data, int k,const char * preDisplay)
{
  printf(preDisplay);
  printf("%d\n",*(data + k - 1));
}

/*
* 使用插入法,寻找第k个大的数
*/
int insertAlgorithm(int * data,int length, int kth)
{
  assert(length >= kth);

  // 建立长度为k的数组
  int* kLengthArray = (int*)malloc(sizeof(int)*kth);

  //将data中的前k个数读入kLengthArray中
  int i = 0;
  for(i = 0; i < kth; i++)
  {
    *(kLengthArray + i) = *(data + i);
  }

  // 使用冒泡法对kLengthArray进行排序
  kLengthArray = bubleSort(kLengthArray, kth);
  // displayArray(kLengthArray,kth,"the fist kLengthArray is: \n");
  // 对剩下的数据进行插入
  int count = kth;       // 从第kth+1个数开始进行插入
  int index = kth - 1;   // 从右往左插入,即从第kth个数开始插入
  for(count = kth; count <= length - 1; count++) // 使用第count个数进行比较,然后插入
  {
    // 得到插入的数在kLengthArray中的位置 index
    for(index = kth - 1; index >= -1; index--)
    {
      if (*(data + count) > *(kLengthArray + index))
      {
        break;
      }
    }

    // 如果index不能维持原值,那么存在一个数在kLengthArray的数的中间,需要进行插入操作
    if (index != kth - 1)
    {
      int i = 0;
      for(i = 0; i < kth - index - 2; i++)
      {
        *(kLengthArray + kth - i - 1) = *(kLengthArray + kth - i - 2);
      }
      *(kLengthArray + index + 1) = *(data + count);
    }
  }
  // displayArray(kLengthArray,kth,"the final kLengthArray is: \n");
  return *(kLengthArray + kth - 1);
}


int main()
{
  int* numbers;
  numbers = generateIntergerArray(TOTAL_NUMBER);
  // displayArray(numbers, TOTAL_NUMBER, "random number generated is:\n");

  clock_t timePointA = clock();
  // 使用冒泡法得到第k个大的数
  int * numbersForBuble = (int*)malloc(sizeof(int)*TOTAL_NUMBER);
  numbersForBuble = bubleSort(numbers,TOTAL_NUMBER);
  displayKthElement(numbersForBuble,KTH,"the k-th element computed by buble algorithm is: ");

  clock_t timePointB = clock();
  // displayArray(numbersForBuble, TOTAL_NUMBER, "sorted number using buble algorithm is:\n");

  clock_t timePointC = clock();
  // 使用插入法得到第k个大的数
  int kthNumber = insertAlgorithm(numbers,TOTAL_NUMBER,KTH);
  printf("the k-th number computed by insert algorithm is: %d\n",kthNumber);
  printf("-----------------------------------------------------------------\n");
  clock_t timePointD = clock();

  printf("timePointB - timePointA = %d\n", timePointB - timePointA);
  printf("timePointD - timePointC = %d\n", timePointD - timePointC);
  printf("-----------------------------------------------------------------\n");

  double timeOfBubleAlgorithm = (double)(timePointB - timePointA)/CLOCKS_PER_SEC;
  double timeOfInsertAlgorithm = (double)(timePointD - timePointC)/CLOCKS_PER_SEC;
  printf("the time buble algorithm use is: %f s\n", timeOfBubleAlgorithm);
  printf("the time insert algorithm use is: %f s\n", timeOfInsertAlgorithm);

  return 0;
}

当TOTAL_NUMBER为500000时,冒泡法需要838.66秒,插入法需要89.5秒。没有书上说的需要几天,可能是现在的计算机计算的快了吧。
当TOTAL_NUMBER为100000时,冒泡法需要33.3秒,插入法需要3.63秒。
当TOTAL_NUMBER为20000时,冒泡法需要1.239秒,插入法需要0.148秒。
当TOTAL_NUMBER为4000时,冒泡法需要0.037秒,插入法需要0.007秒。
当TOTAL_NUMBER为800时,冒泡法需要0.02秒,插入法需要0.001秒。
当TOTAL_NUMBER为160时,冒泡法需要0.01秒,插入法需要0.000秒(程序是这样显示,显然是不可能的,也许超出计程序的精度了吧)。
当TOTAL_NUMBER为32时,冒泡法需要0.0000秒,插入法需要0.0000秒,程序是这样显示,显然是不可能的,也许超出计程序的精度了吧)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值