第八章 排序技术

第8章 排序技术8.1 概述在排序问题中,通常将数据元素成为记录。若待排序序列中的记录已按关键码排好序,称此记录序列为正序;若待排序序列中记录的排列顺序与排好序的顺序正好相反,称此记录序列为逆序或反序。排序的分类内排序是指在排序的整个过程中,待排序的所有记录全部被放在内存中;外排序是指由于待排序的记录个数太多,不能同时放置在内存,而需要将一部分记录放置在内存,另一部分记录放置在外存。可以将平排序方法分为基于比较的排序和不基于比较的排序。8.2插入排序8.2.1 直接插入排序直接插入排序是插入排序中最简单的排序方法,类似于玩纸牌是整理手中纸牌的过程。直接插入排序算法InsertSortvoid InsertSort{int r[],int n}{for(i=2;i<=n;i++){r[0]=r[i];for(j=i-1;r[0]=1;d=d/2){for(i=d+1:i<=n;i++){r[0]=r[i];for(j=i-d;j>0&&r[0]<r[j];j=j-d)r[j+d]=r[0];}}}8.3 交换排序8.3.1 起泡排序起泡排序是交换排序中最简单的排序方法,其基本思想是两辆比较相邻记录的关键码,如果反序则交换,直到没有反序的记录为止。起泡排序算法BubbleSortvoid BubbleSort(int r[],int n){exchange=n;while (exchange!=0){bound=exchange;exchange=0;for(j=1;jr[j+1]){r[j]←→r[j+1];exchange=j;}}}8.3.2 快速排序快速排序是对起泡排序的一种改进,改进的着眼点是:在起泡排序中,记录的比较和移动是在相邻位置进行的,记录每次交换只能后移一个位置,因而总的比较次数和移动次数较多选择轴值有多种方法,最简单的方法是选取第一个记录的关键码,还可以选取中间记录的关键码,或者在每次划分之前比较待排序序列的第一个记录,最后一个记录和中间记录的关键码,选取居中的关键码作为轴值并调换到第一个记录的位置。一次划分的过程为1 初始化2 右侧扫描过程3左侧扫描过程4 重复2 3 步,直到i与j指向同一位置,即轴值记录的最终的位置。快速排序一次划分算法Partitionint Partition(int r[],int first,int end){i=first;j=end;while(i<j){while(i<j&&r[i]<=r[j])j--;if(i<j){r[i]←→r[j];i++;}while (i<j&&r[i]<=r[j])i++;if(i<j){r[j]←→r[i];j--;}}return i;}快速排序算法QuickSortvoid QuickSort(int r[],int first,int end){if(first<end){pivot=Patition(r,first,end);QuickSort(r,first,pivot-1);QuickSort(r,pivot+1,end);}}8.4 选择排序选择排序是一类借助“选择”进行排序的方法,其主要思想是:每趟排序在当前待排序序列中选出关键码最小的记录,添加到有序序列中。选择排序的特点是记录移动的次数较少。8.4.1 简单选择排序简单选择排序是选择排序中最简单的排序方法,其基本思想是:第i趟排序在待排序序列r[i]~r[n](1≤i≤n-1)中选取关键码最小的记录,并和第i个记录交换作为有序序列的第i个记录。简单选择排序算法SelectSortvoid SelectSort(int r[],int n){for(i=1;i<n;i++){index=i;for(j=i+1;j<=n;j++)if(r[j]<r[index])index=j;if(index!=i)r[i]←→r[index];}}8.4.2 堆排序堆排序是简单选择排序的一种改进,改进的着眼点是:如何减少关键码的比较次数。堆排序再选出最小关键码的同时,也找出较小关键码,减少了在后面等选择中的比较次数,从而提高了整个排序的效率。1、 堆的定义堆是具有下列性质的完全二叉树:每个结点的值都小于或等于其左右孩子堆点的值(称为小根堆);或者每个结点的值都大于或等于其左右孩子堆点的值(称为大根堆)从堆的定义可以看出,一个完全二叉树如果是堆,则根节点(称为堆顶)一定是当前堆中所有结点中的最大者或最小者。筛选法调整堆的算法Siftvoid Sift(int r[],int k,int m){i=k;j=2*1;while (j<=m){if(j<m&&r[j]r[j])break;else{r[i]←→r[j];i=j;j=2*i;}}}2、 堆排序堆排序是利用堆的特性进行排序的方法,其基本思想是:首先将待排序的记录序列构造成一个堆,此时,选出了堆中所有记录的最大者即堆顶记录。然后将堆顶记录移走,并将剩余的记录再调整成堆,这样又找出了次大的记录。以此类推,直到堆中只有一个记录为止堆排序算法HearSortvoid HeapSort(int r[],int n){for(i=n/2;i>=1;i--)Sift(r,i,n);for(i=1;i<n;i++){r[1]←→r[n-i+1];Sift(r,i,n-i);}}8.5 归并排序8.5.1 二路归并排序的非递归实现。具体的排序过程是:将具有n个待排序的记录序列看成是n个长度为1的有序序列,然后进行两辆归并,得到[n/2]个长度为2(最后一个有序序列的长度可能是1)的有序序列,再进行两辆归并,得到[n/4]个长度为4的有序序列(最后一个有序序列的长度可能小于4),……直至得到一个长度为n的有序序列。一次病归算法 Mergevoid Merge(int r[],int r1[],int s,int m,int t){i=s;j=m+1;k=s;while (i<=m&&j<=t){if(r[i]<=r[j]) r1[k++]=r[i++];else r1[k++]=r[j++];}if(i<=m)while (i<=m0r1[k++]=r[i++];else while (j<=t)r1[k++]=r[j++];}一趟归并排序算法MergePassvoid MergePass(int r[],int r1[],int n,int h){i=1;while (i<=n-2h+1){Merge(r,r1,i,i+h-1,i+2*h-1);i+=2*h;}if(i<n-h+1)Merge(r,r1,i,i+h-1,n);else for(k=i;k<=n;k++)r1[k]=r[k];}归并排序非递归算法MergeSortvoid MergeSort1(int r[],int r1[],int n){h=1;while(h<n){MergeSort(r,r1,n,h);h=2*h;MergePass(r1,r,n,h);h=2*h;}}8.5.2 二路归并排序的递归实现二路并归排序方法也可以用递归的形式描述,即首先将待排序的记录序列分为两个相等的子序列,并分别将这两个子序列用并归方法进行排序,然后调用一次并归算法Merge,再将这两个有序子序列合并成一个含有全部记录的有序序列。归并排序的递归算法MergeSort2void MergeSort2(int r[],int r1[],int s,int t){if(s==t)r1[s]=r[s];else{m=(s+t)/2;Mergesort2(r,r1,s,m);Mergesort2(r,ri,m+1,t);Merge(r1,r,s,m,t);}}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值