实验4:各种内排序算法

各种内排序算法

简单选择排序

//简单选择排序
void SelectSort(List *list){
    int small,i,j;
    for(i = 0;i < list->n-1;i ++){
        small = i;                                    //标记每次第一位元素下标
        for(j = i+1;j < list->n;j ++){
            if(list->D[j].key < list->D[small].key){  //按非递减顺序比较大小
                small = j;
            }
        }
        if(small != i){                               //判断起始位置是否为最小值
            swap(list->D[j].key,list->D[small].key);  //直接调用algorithm库里的swap函数
        }
    }
}

直接插入排序

//直接插入排序
void InsertSort(List *list){
    int i,j;                                 //i标识待插入元素下标
    for(i = 1;i < list->n;i ++){
        Entry insertItem = list -> D[i];     //标记每次第一位元素
        for(j = i-1;j >= 0;j --){
            //不断将有序序列中元素向后移动,为待插入元素空出一个位置
            if(insertItem.key < list->D[j].key){
                list->D[j+1] = list->D[j];
            }
            else break;
        }
        list->D[j+1] = insertItem;          //待插入元素有序存放至有序序列中
    }
}

冒泡排序

//冒泡排序
void BubbleSort(List *list){
    int i,j;                    //i标识每趟排序范围最后一个元素下标,每趟排序元素下标范围是0~i
    for(i = list->n-1;i > 0;i --){
        BOOL isSwap = FALSE;    //教材这里错了,应该放到第二层循环前
        for(j = 0;j < i;j ++){
            if(list->D[j].key > list->D[j+1].key){
                swap(list->D[j],list->D[j+1]);
                isSwap = TRUE;
            }
        }
        if(!isSwap) break;     //如果本趟排序没有发生元素交换,排序完成
    }
}

快速排序

//序列划分方法
int Partition(List *list,int low,int high){
    int i = low,j = high + 1;
    Entry pivot = list->D[low];                 //pivot是分割元素
    do{
        do i++;
        while(list->D[i].key < pivot.key);      //i前进
        do j--;
        while(list->D[j].key > pivot.key);      //j前进
        if(i < j) swap(list->D[i],list->D[j]);
    }while(i < j);
    swap(list->D[low],list->D[j]);
    return j;                                   //此时j是分割元素下标
}


//快速排序
void QuickSort(List *list,int low,int high){   //快速排序的递归函数
    int k;
    if(low < high){                            //当前待排序序列至少包含2个元素
        k = Partition(list,low,high);
        QuickSort(list,low,k-1);
        QuickSort(list,k+1,high);
    }
}


//函数重载
void QuickSort(List *list){                   //快速排序算法的主调用函数
    QuickSort(list,0,list->n-1);
}

两路合并排序

/*
//序列两路合并方法
//n1和n2是两个子序列长度,low是第一个子序列第一个元素下标
void Merge(List *list,Entry *temp,int low,int n1,int n2){
    int i = low,j = low + n1; //i,j初始时分别指向两个序列的第一个元素
    while(i <= low+n1-1 && j <= low+n1+n2-1){
        if(list->D[i].key <= list->D[j].key)
            *temp++ = list->D[i++];
        else *temp++ = list->D[j++];
    }
    while(i <= low+n1-1)
        *temp++ = list->D[i++];  //剩余元素直接拷贝至temp
    while(j <= low+n1+n2-1)
        *temp++ = list->D[j++];  //剩余元素直接拷贝至temp
}


//两路合并排序算法
void MergeSort(List *list){
    Entry temp[MaxSize];
    int low,n1,n2,i,size = 1;
    while(size < list->n){
        low = 0;      //low是一对待合并序列中第一个序列的第一个元素下标
        while(low+size < list->n){
            //low+size < list->n说明至少存在两个子序列需要合并
            n1 = size;
            if(low+size*2 < list->n) n2 = size;  //计算第二个序列长度
            else n2 = list->n-low-size;
            Merge(list,temp,low,n1,n2);
            low += n1+n2;  //确定下一对待合并序列中第一个序列的第一个元素下标
        }
        for(i = 0;i < list->n;i ++){
            list->D[i] = temp[i];  //复制一趟合并排序结果
        }
        size *= 2;  //子序列长度翻倍
    }
}
*/

//Merge函数,参考了陈慧南老师的《数据结构——C语言描述》教材
void Merge(List *list,int Temp[],int i1,int j1,int i2,int j2,int *k){
    int i = i1,j = i2;
    while((i <= j1)&&(j<=j2)){                       //若两个子序列都不空,则循环
        if(list->D[i].key <= list->D[j].key){
            Temp[(*k)++] = list->D[i++].key;         //将较小元素存入Temp[*k]
        }
        else Temp[(*k)++] = list->D[j++].key;
    }
    while(i <= j1) Temp[(*k)++] = list->D[i++].key;  //将子序列1中剩余元素存入Temp
    while(j <= j2) Temp[(*k)++] = list->D[j++].key;  //将子序列2中剩余元素存入Temp
}


//MergeSort函数,参考了陈慧南老师的《数据结构——C语言描述》教材
void MergeSort(List *list){
    int Temp[MaxSize];
    int i1,j1,i2,j2,i,k,size = 1;              //i1,j1和i2,j2分别是两个子序列的上,下界
    while(size < list->n){
        i1 = 0;
        k = 0;
        while(i1+size < list->n){              //若i1+size < n,则说明存在两个子序列,需要再两两合并
            i2 = i1+size;                      //确定子序列2的下界和子序列1的上界
            j1 = i2-1;
            if(i2+size-1 > list->n-1){         //设置子序列2的上界
                j2 = list->n-1;
            }
            else j2 = i2+size-1;
            Merge(list,Temp,i1,j1,i2,j2,&k);  //合并相邻两个子序列
            i1 = j2+1;                        //确定下一次合并第一个子序列的下界
        }
        for(i = 0;i < k;i ++){
            list->D[i].key = Temp[i];
        }
        size *= 2;                            //子序列长度扩大一倍
    }
}

版权声明:本文为博主原创文章,如有错误,恳请大家在评论区指出,在下不胜感激~如要转载注明出处即可~
本文首发于个人博客:Wonz の Blog

猜你喜欢

转载自blog.csdn.net/Wonz5130/article/details/82292182