第十五周 项目三 归并排序算法的改进
生活随笔
收集整理的這篇文章主要介紹了
第十五周 项目三 归并排序算法的改进
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
/*
* Copyright (c)2017,煙臺大學計算機與控制工程學院
* All rights reserved.
* 文件名稱:項目3.cpp
* 作 者:孫仁圓
* 完成日期:2017年12月27日
* 版 本 號:v1.0
*問題描述:采用歸并排序、快速排序等高效算法進行排序,當數據元素較少時(如n≤64),經常直接使用直接插入排序算法等高復雜度的算法。這樣做,會帶來一定的好處,例如歸并排序減少分配、回收臨時存儲區域的頻次,快速排序減少遞歸層次等。
試按上面的思路,重新實現歸并排序算法。
*輸入描述:無
*程序輸出:測試數據
*/ #include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>
#define MinLength 64 //最短分段長度
typedef int KeyType; //定義關鍵字類型
typedef char InfoType[10];
typedef struct //記錄類型
{ KeyType key; //關鍵字項 InfoType data; //其他數據項,類型為InfoType
} RecType; //排序的記錄類型定義 void GetData(RecType *&R, int n)
{ srand(time(0)); R=(RecType*)malloc(sizeof(RecType)*n); for(int i=0; i<n; i++) R[i].key= rand(); printf("生成了%d條記錄\n", n);
} //對R[low..high]按遞增有序進行直接插入排序
void InsertSort(RecType R[],int low,int high)
{ int i,j; RecType tmp; for (i=low; i<=high; i++) { tmp=R[i]; j=i-1; //從右向左在有序區R[low..i-1]中找R[i]的插入位置 while (j>=low && tmp.key<R[j].key) { R[j+1]=R[j]; //將關鍵字大于R[i].key的記錄后移 j--; } R[j+1]=tmp; //在j+1處插入R[i] }
} //合并兩個有序表
void Merge(RecType R[],int low,int mid,int high)
{ RecType *R1; int i,j,k; i=low,j=mid+1,k=0; //k是R1的下標,i、j分別為第1、2段的下標 R1=(RecType *)malloc((high-low+1)*sizeof(RecType)); //動態分配空間 while (i<=mid && j<=high) //在第1段和第2段均未掃描完時循環 if (R[i].key<=R[j].key) //將第1段中的記錄放入R1中 { R1[k]=R[i]; i++; k++; } else //將第2段中的記錄放入R1中 { R1[k]=R[j]; j++; k++; } while (i<=mid) //將第1段余下部分復制到R1 { R1[k]=R[i]; i++; k++; } while (j<=high) //將第2段余下部分復制到R1 { R1[k]=R[j]; j++; k++; } for (k=0,i=low; i<=high; k++,i++) //將R1復制回R中 R[i]=R1[k];
} //一趟合并
void MergePass(RecType R[],int length,int n) //對整個數序進行一趟歸并
{ int i; for (i=0; i+2*length-1<n; i=i+2*length) //歸并length長的兩相鄰子表 Merge(R,i,i+length-1,i+2*length-1); if (i+length-1<n) //余下兩個子表,后者長度小于length Merge(R,i,i+length-1,n-1); //歸并這兩個子表
} //自底向上的二路歸并算法,但太短的分段,用直接插入完成
void MergeSort(RecType R[],int n)
{ int length, i; for(i=0;i<n;i+=MinLength) //先按最短分段,用插入排序使之分段有序 InsertSort(R, i, ((i+MinLength-1<n)?(i+MinLength-1):n)); for (length=MinLength; length<n; length=2*length) //進行歸并 { MergePass(R,length,n); }
}
int main()
{ int i,n=10000; RecType *R; GetData(R, n); MergeSort(R,n); printf("排序后(前300個):\n"); i=0; while(i<300) { printf("%12d ",R[i].key); i++; if(i%5==0) printf("\n"); } printf("\n"); printf("排序后(后300個):\n"); i=0; while(i<300) { printf("%12d ",R[n-300+i].key); i++; if(i%5==0) printf("\n"); } printf("\n"); free(R);
return 0;
}
總結
以上是生活随笔為你收集整理的第十五周 项目三 归并排序算法的改进的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: dbeaver sql字体异常
- 下一篇: 第十五周 项目一 (3)验证交换排序