数据结构排序算法

来源:互联网 发布:中国期货交易软件 编辑:程序博客网 时间:2024/05/14 05:23
//头文件#include"stdio.h"#include"stdlib.h"#define Max 100         //假设文件长度typedef struct{         //定义记录类型    int key;            //关键字项}RecType;typedef RecType SeqList[Max+1]; //SeqList为顺序表,表中第0个元素作为哨兵int n;                 //顺序表实际的长度//==========直接插入排序法======void InsertSort(SeqList R){       //对顺序表R中的记录R[1‥n]按递增序进行插入排序    int i,j;    for(i=2;i<=n;i++)      //依次插入R[2],……,R[n]  if(R[i].key<R[i-1].key)  {                        //若R[i].key大于等于有序区中所有的keys,则R[i]留在原位   R[0]=R[i];j=i-1;        //R[0]是R[i]的副本    do {              //从右向左在有序区R[1‥i-1]中查找R[i]的位置   R[j+1]=R[j];      //将关键字大于R[i].key的记录后移   j--;     }  while(R[0].key<R[j].key);   //当R[i].key≥R[j].key 是终止    R[j+1]=R[0];                //R[i]插入到正确的位置上}//endif }//==========冒泡排序======= typedef enum{FALSE,TRUE} Boolean;  //FALSE为0,TRUE为1void BubbleSort(SeqList R) {             //自下向上扫描对R做冒泡排序    int i,j;     Boolean exchange;     //交换标志  for(i=1;i<n;i++) {    //最多做n-1趟排序exchange=FALSE;       //本趟排序开始前,交换标志应为假for(j=n-1;j>=i;j--)       //对当前无序区R[i‥n] 自下向上扫描    if(R[j+1].key<R[j].key){    //两两比较,满足条件交换记录R[0]=R[j+1];            //R[0]不是哨兵,仅做暂存单元R[j+1]=R[j];R[j]=R[0];exchange=TRUE;         //发生了交换,故将交换标志置为真    }if(! exchange)           //本趟排序未发生交换,提前终止算法    return;    }//endfor(为循环)}//1.========一次划分函数=====int Partition(SeqList R,int i,int j){      //   对R[i‥j]做一次划分,并返回基准记录的位置    RecType pivot=R[i];       //用第一个记录作为基准    while(i<j) {              //从区间两端交替向中间扫描,直到i=j while(i<j &&R[j].key>=pivot.key)   //基准记录pivot相当与在位置i上    j--;      //从右向左扫描,查找第一个关键字小于pivot.key的记录R[j]if(i<j)   //若找到的R[j].key < pivot.key,则    R[i++]=R[j];  //交换R[i]和R[j],交换后i指针加1while(i<j &&R[i].key<=pivot.key)       //基准记录pivot相当与在位置j上    i++;     //从左向右扫描,查找第一个关键字小于pivot.key的记录R[i]if(i<j)   //若找到的R[i].key > pivot.key,则    R[j--]=R[i]; //交换R[i]和R[j],交换后j指针减1    }    R[i]=pivot;    //此时,i=j,基准记录已被最后定位    return i;      //返回基准记录的位置}//2.=====快速排序===========void QuickSort(SeqList R,int low,int high){                 //R[low..high]快速排序    int pivotpos;            //划分后基准记录的位置    if(low<high) {           //仅当区间长度大于1时才排序pivotpos=Partition(R,low,high);  //对R[low..high]做一次划分,得到基准记录的位置QuickSort(R,low,pivotpos-1);       //对左区间递归排序QuickSort(R,pivotpos+1,high);      //对右区间递归排序    }}//======直接选择排序========void SelectSort(SeqList R){    int i,j,k;    for(i=1;i<n;i++){         //做第i趟排序(1≤i≤n-1)k=i;for(j=i+1;j<=n;j++)  //在当前无序区R[i‥n]中选key最小的记录R[k]   if(R[j].key<R[k].key)k=j;         //k记下目前找到的最小关键字所在的位置if(k!=i) {  //       //交换R[i]和R[k]   R[0]=R[i];R[i]=R[k];R[k]=R[0];} //endif    } //endfor}//==========大根堆调整函数=======void Heapify(SeqList R,int low,int high){     // 将R[low..high]调整为大根堆,除R[low]外,其余结点均满足堆性质    int large;        //large指向调整结点的左、右孩子结点中关键字较大者    RecType temp=R[low]; //暂存调整结点    for(large=2*low; large<=high;large*=2){  //R[low]是当前调整结点      //若large>high,则表示R[low]是叶子,调整结束;否则先令large指向R[low]的左孩子if(large<high && R[large].key<R[large+1].key)    large++; //若R[low]的右孩子存在且关键字大于左兄弟,则令large指向它        //现在R[large]是调整结点R[low]的左右孩子结点中关键字较大者if(temp.key>=R[large].key)  //temp始终对应R[low]    break;  //当前调整结点不小于其孩子结点的关键字,结束调整R[low]=R[large];  //相当于交换了R[low]和R[large]low=large;  //令low指向新的调整结点,相当于temp已筛下到large的位置   }   R[low]=temp;   //将被调整结点放入最终位置上}//==========构造大根堆==========void BuildHeap(SeqList R){       //将初始文件R[1..n]构造为堆    int i;    for(i=n/2;i>0;i--)Heapify(R,i,n);      //将R[i..n]调整为大根堆}//==========堆排序===========void HeapSort(SeqList R){               //对R[1..n]进行堆排序,不妨用R[0]做暂存单元    int i;    BuildHeap(R);  //将R[1..n]构造为初始大根堆    for(i=n;i>1;i--){      //对当前无序区R[1..i]进行堆排序,共做n-1趟。R[0]=R[1]; R[1]=R[i];R[i]=R[0];     //将堆顶和堆中最后一个记录交换Heapify(R,1,i-1);   //将R[1..i-1]重新调整为堆,仅有R[1]可能违反堆性质。    }}//=====将两个有序的子序列R[low..m]和R[m+1..high]归并成有序的序列R[low..high]==void Merge(SeqList R,int low,int m,int high){     int i=low,j=m+1,p=0; //置初始值    RecType *R1;   //R1为局部量    R1=(RecType *)malloc((high-low+1)*sizeof(RecType)); //申请空间    while(i<=m && j<=high)      //两个子序列非空时取其小者输出到R1[p]上R1[p++]=(R[i].key<=R[j].key)? R[i++]:R[j++];    while(i<=m)    //若第一个子序列非空,则复制剩余记录到R1R1[p++]=R[i++];    while(j<=high)     //若第二个子序列非空,则复制剩余记录到R1中R1[p++]=R[j++];    for(p=0,i=low;i<=high;p++,i++)R[i]=R1[p];    //归并完成后将结果复制回R[low..high]}//=========对R[1..n]做一趟归并排序========void MergePass(SeqList R,int length){     int i;    for(i=1;i+2*length-1<=n;i=i+2*length)Merge(R,i,i+length-1,i+2*length-1); //归并长度为length的两个相邻的子序列    if(i+length-1<n)   //尚有一个子序列,其中后一个长度小于lengthMerge(R,i,i+length-1,n);  //归并最后两个子序列        //注意:若i≤n且i+length-1≥n时,则剩余一个子序列轮空,无须归并}//========== 自底向上对R[1..n]做二路归并排序===============void MergeSort(SeqList R){    int length;    for(length=1;length<n;length*=2)     //做[lgn]趟排序MergePass(R,length);     //有序长度≥n时终止}//==========输入顺序表========void input_int(SeqList R){               int i;    printf("\n--请输入需要的数据个数:");    scanf("%d",&n);    printf("\n--请输入 %d 个数据:\n",n);    for(i=1;i<=n;i++)scanf("%d",&R[i].key);}//==========输出顺序表========void output_int(SeqList R){    int i;printf("---------------------------------\n");    for(i=1;i<=n;i++)    printf("%d  ",R[i].key);}//主菜单void menu(SeqList R){int choice = 0;printf("******** 简单排序 ****************\n");    printf("1:--直接插入排序\n");    printf("2:--冒泡排序\n");    printf("3:--快速排序\n");    printf("4:--直接选择排序\n");    printf("5:--堆排序\n");    printf("6:--归并排序\n");    printf("7:--退出\n");    printf("*********************************\n");printf("--请输入操作数:");scanf("%d",&choice);    switch (choice){case 1: system("CLS");    InsertSort(R); printf("\n--直接插入排序结果如下:\n");    output_int(R);    printf("\n\n--按任意键返回--\n");getchar();getchar();system("CLS");menu(R);//值为1,直接插入排序case 2: system("CLS");    BubbleSort(R);printf("\n--冒泡排序排序结果如下:\n");    output_int(R);printf("\n\n--按任意键返回--\n");getchar();getchar();system("CLS");menu(R);       //值为2,冒泡法排序case 3: system("CLS");    QuickSort(R,1,n);printf("\n--快速排序结果如下:\n");    output_int(R);printf("\n\n--按任意键返回--\n");getchar();getchar();system("CLS");menu(R);    //值为3,快速排序case 4: system("CLS");    SelectSort(R); printf("\n--直接选择排序结果如下:\n");    output_int(R);printf("\n\n--按任意键返回--\n");getchar();getchar();system("CLS");menu(R);       //值为4,直接选择排序case 5: system("CLS");    HeapSort(R);printf("\n--堆排序结果如下:\n");    output_int(R);printf("\n\n--按任意键返回--\n");getchar();getchar();system("CLS");menu(R);         //值为5,堆排序case 6: system("CLS");    MergeSort(R); printf("\n--归并排序结果如下:\n");    output_int(R);printf("\n\n--按任意键返回--\n");getchar();getchar();system("CLS");menu(R);//值为6,归并排序case 7: system("CLS");printf("\n--退出排序--\n");exit(0);                    //值为7,结束程序    }}//主函数#include "WW.h"void main(){    SeqList R;    input_int(R);system("CLS");menu(R);}


原创粉丝点击