当前位置:首页 » 操作系统 » 综合排序算法

综合排序算法

发布时间: 2023-01-09 18:35:01

1. 排序方法有哪几种排序方法的相关知识

1、排序方法有10种,分别是:冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序。
2、冒泡排序算法是把较小的元素往前调或者把较大的元素往后调。这种方法主要是通过对相邻两个元素进行大小的比较,根据比较结果和算法规则对该二元素的位置进行交换,这样逐个依次进行比较和交换,就能达到排序目的。
3、选择排序算法的基本思路是为每一个位置选择当前最小的元素。选择排序的基本思想是,基于直接选择排序和堆排序这两种基本的简单排序方法。
4、插入排序算法是基于某序列已经有序排列的情况下,通过一次插入一个元素的方式按照原有排序方式增加元素。

2. 淘宝商品综合排序什么算法

商品综合排序跟10项因素相关,具体如下
影响宝贝排名的重要因素的权重占比:
成交量:15%
好评率:10%
收藏量:8%
上下架:12%
转化率:14%
橱窗推荐:10%
回购率:10%
DSR:8% 卖家服务评级系统(Detail Seller Rating)

3. 排序方法有哪几种

排序方法有:

一、直接插入排序

原理:从待排序的数中选出一个来,插入到前面的合适位置。

二、选择排序

与直接插入排序正好相反,选择排序是从待排序的数中选出最小的放在已经排好的后面,这个算法选数耗时。

三、快速排序

快速排序简称快排,是一种比较快的排序,适合基本无序的数据,为什么这么说呢?下面我说下快排的思路:设置两个指针:i和j,分别指向第一个和最后一个,i像后移动,j向前移动,选第一个数为标准(一般这样做,当然快排的关键就是这个“标准”的选取),从后面开始。

找到第一个比标准小的数,互换位置,然后再从前面,找到第一个比标准大的数,互换位置,第一趟的结果就是标准左边的都小于标准,右边的都大于标准(但不一定有序),分成两拨后,继续递归的使用上述方法,最终有序!

四、冒泡排序

冒泡排序是一种很简单,不论是理解还是时间起来都比较容易的一种排序算法,思路简单:小的数一点一点向前起泡,最终有序。

五、归并排序

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

首先考虑下如何将将二个有序数列合并。这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可。

4. C语言 排序算法综合系统

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<iostream>
using namespace std;
void find(int *a,int n);
void input(int pIn[], int n);
void del(int *a,int n);
void Swap(int *a, int *b);
int Partition(int a[], int p, int r);
void arrange(int *c,int length);
template <class Type>
/* 为了便于维护,现在把排序封装在类ArraySort内
*/
class ArraySort
{
private: int elem; //elem的值决定按升序还是降序
int len; //排序数组的长度
Type *b; //排序时用与交换的数组
Type *a; //用来存放要排序的数组;
public:
void set(Type c[],int k); //接收要排序的数组及数组长度
void Sort(); //进行排序
void MergeSort(int ,int );
void Merge(int ,int ,int); //进行合并
void Copy(int ,int); //复制一个数组到另一个数组
void ArPrint(); //输出数组元素
void ReturnCopy(Type c[]); //把已经排序数组返回给原数组
~ArraySort();
ArraySort(int k=0){
elem=k;
len=0;
a=NULL;
b=NULL;
}
};
template<class Type>
void ArraySort<Type>::set(Type c[],int k )
{ int m;
len=k;
//len=c.length;
a=new Type[len];
b=new Type[len];
if((a==NULL)||(b==NULL))
{ cout<<"can't allocate more memory,terminating."<<endl;
exit(1);
}
else{
for(int i=0;i<len;i++)
a[i]=c[i];
}
cout<<" input the number 0 or 1:"<<endl;
cout<<"0 min to max:"<<endl;
cout<<"1 max to min"<<endl;
cin>>m;
if(m>=0&&m<=1)
elem=m;
else {
cout<<"You input a illegal number!!";
cout<<" input the number 0 or 1:"<<endl;
cout<<"0 min to max:"<<endl;
cout<<"1 max to min"<<endl;
}
}
template <class Type>
void ArraySort<Type>::Sort()
{
MergeSort(0,len-1);
}
template <class Type>
void ArraySort<Type>::Merge(int left,int m,int right)
{
int i=left,
j=m+1,
k=left;
if(elem==0){
while((i<=m)&&(j<=right))
if(a[i]<=a[j]) b[k++]=a[i++];
else b[k++]=a[j++];
}
else{
while((i<=m)&&(j<=right))
if(a[i]>=a[j]) b[k++]=a[i++];
else b[k++]=a[j++];
}
while(i<=m)
b[k++]=a[i++];
while(j<=right)
b[k++]=a[j++];
}
template <class Type>
void ArraySort<Type>::Copy(int left,int right)
{
for(int i=left;i<=right;i++)
a[i]=b[i];
}
template <class Type>
void ArraySort<Type>::ArPrint()
{
// int len=this.a.length;
cout<<"The length of array is :"<<len<<endl;
cout<<"The elements of array is :"<<endl;
for(int i=0;i<len;i++)
cout<<" "<<a[i];
if(i/5==0)
cout<<endl;
}
template <class Type>
void ArraySort<Type>::MergeSort(int left,int right)
{
if(left<right){
int i=(left+right)/2;
MergeSort(left,i);
MergeSort(i+1,right);
Merge(left,i,right);
Copy(left,right);
}
}
template <class Type>
void ArraySort<Type>::ReturnCopy(Type c[])
{
for(int i=0;i<len;i++)
c[i]=a[i];
}
template <class Type>
ArraySort<Type>::~ArraySort()
{
delete a;
delete b;
}

void qSort(int pIn[], int p/*0*/, int r/*r = N - 1*/);
main()
{ char c;
int i,a[12]={6,11,12,5,1,13,8,9,14,7,10},exit=1;
do
{
system("cls");
for(i=0;i<80;i++)
printf("*");
printf("\t 1:选择排序法\n");
printf("\t 2:冒泡排序法\n");
printf("\t 3:插入排序法\n");
printf("\t 4:合并排序法\n");
printf("\t 5:退出\n");
printf("\t 请选择输入选项【1\\2\\3\\4\\5】:\n");
do
{
c=getch();
}while(c!='1'&&c!='2'&&c!='3'&&c!='4'&&c!='5');

switch(c)
{ case '1':input(a,11);
cout<<endl;
for(i=0;i<11;i++)
cout<<a[i]<<" ";
cout<<endl;
break;
case '2':del(a,11);
cout<<endl;
for(i=0;i<11;i++)
cout<<a[i]<<" ";
cout<<endl;break;
case '3':find(a,11); break;
case '4':arrange(a,11); break;
case '5':exit=0;
}
printf("按任意键返回主菜单:\n");
getche();

}while(exit);
}
void input(int pIn[], int n)
{
qSort(pIn, 0, n-1);
}
void Swap(int *a, int *b){
int c = *a;
*a = *b;
*b = c;
}

int Partition(int a[], int p, int r)
{
int i = p;
int j = r + 1;
int x = a[p];

while(1){
while (i <= r && a[++i] < x); // 如果你要从大到小排序就改x前的<为>
while (j >= p && a[--j] > x); //同时这的>也要改为<
if (i >= j) break;
Swap(&a[i], &a[j]);
}

if (i == j) {
j --;
}

a[p] = a[j];
a[j] = x;
return j;
}

void qSort(int pIn[], int p/*0*/, int r/*r = N - 1*/)
{
if (p < r) {
int q = Partition(pIn, p, r);
qSort(pIn, p, q - 1);
qSort(pIn, q + 1, r);
}
}
void del(int *a,int n)//冒泡
{
int i,j,k;
for(i=0;i<=n-2;i++)
for(j=0;j<=n-2-i;j++)
if(a[j]>a[j+1])//如果你要从大到小排序就改>为<
{
k=a[j];
a[j]=a[j+1];
a[j+1]=k;
}
}

void find(int *a,int n)//插入
{
int i, j, x;
for(i = 1;i < n;i++)
{
x = a[i];
j = i - 1;

while(j >= 0 && a[j] > x){
a[j+1] = a[j];
j--;
}

a[j+1] = x;
}
for(i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
void arrange(int *c,int length)//组合
{
int i;

ArraySort<int > as;
as.set(c,length);
cout<<"排序前的数组元素序列:"<<endl;
for( i=0;i<length;i++)
cout<<" "<<c[i];
cout<<endl;
as.Sort();

as.ReturnCopy(c);

cout<<"排序后的数组元素序列:"<<endl;
for( i=0;i<length;i++)
cout<<" "<<c[i];
cout<<endl;
}
楼主做了我2个多小时啊。。TC不能识别有的头文件哈,我已经用VC6.0测试过了

5. 常用的数据排序算法有哪些,各有什么特点举例结合一种排序算法并应用数组进行数据排序。

排序简介
排序是数据处理中经常使用的一种重要运算,在计算机及其应用系统中,花费在排序上的时间在系统运行时间中占有很大比重;并且排序本身对推动算法分析的发展也起很大作用。目前已有上百种排序方法,但尚未有一个最理想的尽如人意的方法,本章介绍常用的如下排序方法,并对它们进行分析和比较。

1、插入排序(直接插入排序、折半插入排序、希尔排序);
2、交换排序(起泡排序、快速排序);
3、选择排序(直接选择排序、堆排序);
4、归并排序;
5、基数排序;

学习重点
1、掌握排序的基本概念和各种排序方法的特点,并能加以灵活应用;
2、掌握插入排序(直接插入排序、折半插入排序、希尔排序)、交换排序(起泡排序、快速排序)、选择排序(直接选择排序、堆排序)、二路归并排序的方法及其性能分析方法;
3、了解基数排序方法及其性能分析方法。

排序(sort)或分类

所谓排序,就是要整理文件中的记录,使之按关键字递增(或递减)次序排列起来。其确切定义如下:
输入:n个记录R1,R2,…,Rn,其相应的关键字分别为K1,K2,…,Kn。
输出:Ril,Ri2,…,Rin,使得Ki1≤Ki2≤…≤Kin。(或Ki1≥Ki2≥…≥Kin)。

1.被排序对象--文件
被排序的对象--文件由一组记录组成。
记录则由若干个数据项(或域)组成。其中有一项可用来标识一个记录,称为关键字项。该数据项的值称为关键字(Key)。
注意:
在不易产生混淆时,将关键字项简称为关键字。

2.排序运算的依据--关键字
用来作排序运算依据的关键字,可以是数字类型,也可以是字符类型。
关键字的选取应根据问题的要求而定。
【例】在高考成绩统计中将每个考生作为一个记录。每条记录包含准考证号、姓名、各科的分数和总分数等项内容。若要惟一地标识一个考生的记录,则必须用"准考证号"作为关键字。若要按照考生的总分数排名次,则需用"总分数"作为关键字。

排序的稳定性

当待排序记录的关键字均不相同时,排序结果是惟一的,否则排序结果不唯一。
在待排序的文件中,若存在多个关键字相同的记录,经过排序后这些具有相同关键字的记录之间的相对次序保持不变,该排序方法是稳定的;若具有相同关键字的记录之间的相对次序发生变化,则称这种排序方法是不稳定的。
注意:
排序算法的稳定性是针对所有输入实例而言的。即在所有可能的输入实例中,只要有一个实例使得算法不满足稳定性要求,则该排序算法就是不稳定的。

排序方法的分类

1.按是否涉及数据的内、外存交换分
在排序过程中,若整个文件都是放在内存中处理,排序时不涉及数据的内、外存交换,则称之为内部排序(简称内排序);反之,若排序过程中要进行数据的内、外存交换,则称之为外部排序。
注意:
① 内排序适用于记录个数不很多的小文件
② 外排序则适用于记录个数太多,不能一次将其全部记录放人内存的大文件。

2.按策略划分内部排序方法
可以分为五类:插入排序、选择排序、交换排序、归并排序和分配排序。

排序算法分析

1.排序算法的基本操作
大多数排序算法都有两个基本的操作:
(1) 比较两个关键字的大小;
(2) 改变指向记录的指针或移动记录本身。
注意:
第(2)种基本操作的实现依赖于待排序记录的存储方式。

2.待排文件的常用存储方式
(1) 以顺序表(或直接用向量)作为存储结构
排序过程:对记录本身进行物理重排(即通过关键字之间的比较判定,将记录移到合适的位置)

(2) 以链表作为存储结构
排序过程:无须移动记录,仅需修改指针。通常将这类排序称为链表(或链式)排序;

(3) 用顺序的方式存储待排序的记录,但同时建立一个辅助表(如包括关键字和指向记录位置的指针组成的索引表)
排序过程:只需对辅助表的表目进行物理重排(即只移动辅助表的表目,而不移动记录本身)。适用于难于在链表上实现,仍需避免排序过程中移动记录的排序方法。

3.排序算法性能评价
(1) 评价排序算法好坏的标准
评价排序算法好坏的标准主要有两条:
① 执行时间和所需的辅助空间
② 算法本身的复杂程度

(2) 排序算法的空间复杂度
若排序算法所需的辅助空间并不依赖于问题的规模n,即辅助空间是O(1),则称之为就地排序(In-PlaceSou)。
非就地排序一般要求的辅助空间为O(n)。

(3) 排序算法的时间开销
大多数排序算法的时间开销主要是关键字之间的比较和记录的移动。有的排序算法其执行时间不仅依赖于问题的规模,还取决于输入实例中数据的状态。

文件的顺序存储结构表示

#define n l00 //假设的文件长度,即待排序的记录数目
typedef int KeyType; //假设的关键字类型
typedef struct{ //记录类型
KeyType key; //关键字项
InfoType otherinfo;//其它数据项,类型InfoType依赖于具体应用而定义
}RecType;
typedef RecType SeqList[n+1];//SeqList为顺序表类型,表中第0个单元一般用作哨兵
注意:
若关键字类型没有比较算符,则可事先定义宏或函数来表示比较运算。
【例】关键字为字符串时,可定义宏"#define LT(a,b)(Stromp((a),(b))<0)"。那么算法中"a<b"可用"LT(a,b)"取代。若使用C++,则定义重载的算符"<"更为方便。

按平均时间将排序分为四类:

(1)平方阶(O(n2))排序
一般称为简单排序,例如直接插入、直接选择和冒泡排序;

(2)线性对数阶(O(nlgn))排序
如快速、堆和归并排序;

(3)O(n1+£)阶排序
£是介于0和1之间的常数,即0<£<1,如希尔排序;

(4)线性阶(O(n))排序
如桶、箱和基数排序。

各种排序方法比较

简单排序中直接插入最好,快速排序最快,当文件为正序时,直接插入和冒泡均最佳。

影响排序效果的因素

因为不同的排序方法适应不同的应用环境和要求,所以选择合适的排序方法应综合考虑下列因素:
①待排序的记录数目n;
②记录的大小(规模);
③关键字的结构及其初始状态;
④对稳定性的要求;
⑤语言工具的条件;
⑥存储结构;
⑦时间和辅助空间复杂度等。

不同条件下,排序方法的选择

(1)若n较小(如n≤50),可采用直接插入或直接选择排序。
当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插人,应选直接选择排序为宜。
(2)若文件初始状态基本有序(指正序),则应选用直接插人、冒泡或随机的快速排序为宜;
(3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或归并排序。
快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;
堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。
若要求排序稳定,则可选用归并排序。但本章介绍的从单个记录起进行两两归并的 排序算法并不值得提倡,通常可以将它和直接插入排序结合在一起使用。先利用直接插入排序求得较长的有序子文件,然后再两两归并之。因为直接插入排序是稳定的,所以改进后的归并排序仍是稳定的。

4)在基于比较的排序方法中,每次比较两个关键字的大小之后,仅仅出现两种可能的转移,因此可以用一棵二叉树来描述比较判定过程。
当文件的n个关键字随机分布时,任何借助于"比较"的排序算法,至少需要O(nlgn)的时间。
箱排序和基数排序只需一步就会引起m种可能的转移,即把一个记录装入m个箱子之一,因此在一般情况下,箱排序和基数排序可能在O(n)时间内完成对n个记录的排序。但是,箱排序和基数排序只适用于像字符串和整数这类有明显结构特征的关键字,而当关键字的取值范围属于某个无穷集合(例如实数型关键字)时,无法使用箱排序和基数排序,这时只有借助于"比较"的方法来排序。
若n很大,记录的关键字位数较少且可以分解时,采用基数排序较好。虽然桶排序对关键字的结构无要求,但它也只有在关键字是随机分布时才能使平均时间达到线性阶,否则为平方阶。同时要注意,箱、桶、基数这三种分配排序均假定了关键字若为数字时,则其值均是非负的,否则将其映射到箱(桶)号时,又要增加相应的时间。
(5)有的语言(如Fortran,Cobol或Basic等)没有提供指针及递归,导致实现归并、快速(它们用递归实现较简单)和基数(使用了指针)等排序算法变得复杂。此时可考虑用其它排序。
(6)本章给出的排序算法,输人数据均是存储在一个向量中。当记录的规模较大时,为避免耗费大量的时间去移动记录,可以用链表作为存储结构。譬如插入排序、归并排序、基数排序都易于在链表上实现,使之减少记录的移动次数。但有的排序方法,如快速排序和堆排序,在链表上却难于实现,在这种情况下,可以提取关键字建立索引表,然后对索引表进行排序。然而更为简单的方法是:引人一个整型向量t作为辅助表,排序前令t[i]=i(0≤i<n),若排序算法中要求交换R[i]和R[j],则只需交换t[i]和t[j]即可;排序结束后,向量t就指示了记录之间的顺序关系:
R[t[0]].key≤R[t[1]].key≤…≤R[t[n-1]].key
若要求最终结果是:
R[0].key≤R[1].key≤…≤R[n-1].key
则可以在排序结束后,再按辅助表所规定的次序重排各记录,完成这种重排的时间是O(n)。

6. 综合排序算法的比较

#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为1
void BubbleSort(SeqList R) { //自下向上扫描对R做冒泡排序
int i,j;
bool 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指针加1
while(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) //若第一个子序列非空,则复制剩余记录到R1
R1[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) //尚有一个子序列,其中后一个长度小于length
Merge(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( "Please input num(int): ");
scanf( "%d ",&n);
printf( "Plase input %d integer: ",n);
for(i=1;i <=n;i++)
scanf( "%d ",&R[i].key);
}
//==========输出顺序表========
void output_int(SeqList R) {
int i;
for(i=1;i <=n;i++)
printf( "%4d ",R[i].key);
}
//==========主函数======
void main() {
int i;
SeqList R;
input_int(R);
printf( "\t******** Select **********\n ");
printf( "\t1: Insert Sort\n ");
printf( "\t2: Bubble Sort\n ");
printf( "\t3: Quick Sort\n ");
printf( "\t4: Straight Selection Sort\n ");
printf( "\t5: Heap Sort\n ");
printf( "\t6: Merge Sort\n ");
printf( "\t7: Exit\n ");
printf( "\t***************************\n ");
scanf( "%d ",&i); //输入整数1-7,选择排序方式
switch (i){
case 1: InsertSort(R);
break; //值为1,直接插入排序
case 2: BubbleSort(R);
break; //值为2,冒泡法排序
case 3: QuickSort(R,1,n);
break; //值为3,快速排序
case 4: SelectSort(R);
break; //值为4,直接选择排序
case 5: HeapSort(R);
break; //值为5,堆排序
case 6: MergeSort(R);
break; //值为6,归并排序
case 7: exit(0); //值为7,结束程序
}
printf( "Sort reult: ");
output_int(R);
}

7. 数据结构课程设计的各种排序算法的综合比较 哪位大神帮写一下~

排序法
平均时间
最差情形
稳定度
额外空间
备注
冒泡
O(n2)
O(n2)
稳定
O(1)
n小时较好
交换
O(n2)
O(n2)
不稳定
O(1)
n小时较好
选择
O(n2)
O(n2)
不稳定
O(1)
n小时较好
插入
O(n2)
O(n2)
稳定
O(1)
大部分已排序时较好
基数
O(logRB)
O(logRB)
稳定
O(n)
B是真数(0-9),R是基数(个十百)
Shell
O(nlogn)
O(ns)
1<s<2
不稳定
O(1)
s是所选分组
快速
O(nlogn)
O(n2)
不稳定
O(nlogn)
n大时较好
归并
O(nlogn)
O(nlogn)
稳定
O(1)
n大时较好

O(nlogn)
O(nlogn)
不稳定
O(1)
n大时较好

8. 排序算法有多少种

排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列。
排序就是把集合中的元素按照一定的次序排序在一起。一般来说有升序排列和降序排列2种排序,在算法中有8中基本排序:
(1)冒泡排序;
(2)选择排序;
(3)插入排序;
(4)希尔排序;
(5)归并排序;
(6)快速排序;
(7)基数排序;
(8)堆排序;
(9)计数排序;
(10)桶排序。
插入排序
插入排序算法是基于某序列已经有序排列的情况下,通过一次插入一个元素的方式按照原有排序方式增加元素。这种比较是从该有序序列的最末端开始执行,即要插入序列中的元素最先和有序序列中最大的元素比较,若其大于该最大元素,则可直接插入最大元素的后面即可,否则再向前一位比较查找直至找到应该插入的位置为止。插入排序的基本思想是,每次将1个待排序的记录按其关键字大小插入到前面已经排好序的子序列中,寻找最适当的位置,直至全部记录插入完毕。执行过程中,若遇到和插入元素相等的位置,则将要插人的元素放在该相等元素的后面,因此插入该元素后并未改变原序列的前后顺序。我们认为插入排序也是一种稳定的排序方法。插入排序分直接插入排序、折半插入排序和希尔排序3类。
冒泡排序
冒泡排序算法是把较小的元素往前调或者把较大的元素往后调。这种方法主要是通过对相邻两个元素进行大小的比较,根据比较结果和算法规则对该二元素的位置进行交换,这样逐个依次进行比较和交换,就能达到排序目的。冒泡排序的基本思想是,首先将第1个和第2个记录的关键字比较大小,如果是逆序的,就将这两个记录进行交换,再对第2个和第3个记录的关键字进行比较,依次类推,重复进行上述计算,直至完成第(n一1)个和第n个记录的关键字之间的比较,此后,再按照上述过程进行第2次、第3次排序,直至整个序列有序为止。排序过程中要特别注意的是,当相邻两个元素大小一致时,这一步操作就不需要交换位置,因此也说明冒泡排序是一种严格的稳定排序算法,它不改变序列中相同元素之间的相对位置关系。
选择排序
选择排序算法的基本思路是为每一个位置选择当前最小的元素。选择排序的基本思想是,基于直接选择排序和堆排序这两种基本的简单排序方法。首先从第1个位置开始对全部元素进行选择,选出全部元素中最小的给该位置,再对第2个位置进行选择,在剩余元素中选择最小的给该位置即可;以此类推,重复进行“最小元素”的选择,直至完成第(n-1)个位置的元素选择,则第n个位置就只剩唯一的最大元素,此时不需再进行选择。使用这种排序时,要注意其中一个不同于冒泡法的细节。举例说明:序列58539.我们知道第一遍选择第1个元素“5”会和元素“3”交换,那么原序列中的两个相同元素“5”之间的前后相对顺序就发生了改变。因此,我们说选择排序不是稳定的排序算法,它在计算过程中会破坏稳定性。
快速排序
快速排序的基本思想是:通过一趟排序算法把所需要排序的序列的元素分割成两大块,其中,一部分的元素都要小于或等于另外一部分的序列元素,然后仍根据该种方法对划分后的这两块序列的元素分别再次实行快速排序算法,排序实现的整个过程可以是递归的来进行调用,最终能够实现将所需排序的无序序列元素变为一个有序的序列。
归并排序
归并排序算法就是把序列递归划分成为一个个短序列,以其中只有1个元素的直接序列或者只有2个元素的序列作为短序列的递归出口,再将全部有序的短序列按照一定的规则进行排序为长序列。归并排序融合了分治策略,即将含有n个记录的初始序列中的每个记录均视为长度为1的子序列,再将这n个子序列两两合并得到n/2个长度为2(当凡为奇数时会出现长度为l的情况)的有序子序列;将上述步骤重复操作,直至得到1个长度为n的有序长序列。需要注意的是,在进行元素比较和交换时,若两个元素大小相等则不必刻意交换位置,因此该算法不会破坏序列的稳定性,即归并排序也是稳定的排序算法。

9. 试说明对长度为n的元素表进行综合并排序,时间复杂度是如何计算的

"综合并排序"是什么意思?
分析执行过程
for(int i=0;i<n;i++) {}
是o(n)
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {}
} 是o(n2)
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
for(int k=0;k<n;k++) {}
}
} 是o(n3)
for(int i=0;i<n;i++) {}
for(int j=0;j<n;j++) {}
是o(n)
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {}
}
for(int j=0;j<n;j++) {}
是o(n2)
也就是不管平行的循环有多少,只管嵌套最深的那个循环有几层
============================================================
分析一下归并排序的时间复杂度,一趟归并需要将SR[1]~SR[n]中相邻的长度为h的有序序列进行两两归并。并将结果放到TR1[1]~TR1[n]中,这需要将待排序序列中的所有记录扫描一遍,因此耗费O(n)时间,而由完全二叉树的深度可知,整个归并排序需要进行.log2n.次,因此,总的时间复杂度为O(nlogn),而且这是归并排序算法中最好、最坏、平均的时间性能。
由于归并排序在归并过程中需要与原始记录序列同样数量的存储空间存放归并结果以及递归时深度为log2n的栈空间,因此空间复杂度为O(n+logn),也就是O(n)。

10. 常用的排序算法都有哪些

排序算法 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
分类
在计算机科学所使用的排序算法通常被分类为:
计算的复杂度(最差、平均、和最好表现),依据串行(list)的大小(n)。一般而言,好的表现是O。(n log n),且坏的行为是Ω(n2)。对于一个排序理想的表现是O(n)。仅使用一个抽象关键比较运算的排序算法总平均上总是至少需要Ω(n log n)。
记忆体使用量(以及其他电脑资源的使用)
稳定度:稳定排序算法会依照相等的关键(换言之就是值)维持纪录的相对次序。也就是一个排序算法是稳定的,就是当有两个有相等关键的纪录R和S,且在原本的串行中R出现在S之前,在排序过的串行中R也将会是在S之前。
一般的方法:插入、交换、选择、合并等等。交换排序包含冒泡排序(bubble sort)和快速排序(quicksort)。选择排序包含shaker排序和堆排序(heapsort)。
当相等的元素是无法分辨的,比如像是整数,稳定度并不是一个问题。然而,假设以下的数对将要以他们的第一个数字来排序。
(4, 1) (3, 1) (3, 7) (5, 6)
在这个状况下,有可能产生两种不同的结果,一个是依照相等的键值维持相对的次序,而另外一个则没有:
(3, 1) (3, 7) (4, 1) (5, 6) (维持次序)
(3, 7) (3, 1) (4, 1) (5, 6) (次序被改变)
不稳定排序算法可能会在相等的键值中改变纪录的相对次序,但是稳定排序算法从来不会如此。不稳定排序算法可以被特别地时作为稳定。作这件事情的一个方式是人工扩充键值的比较,如此在其他方面相同键值的两个物件间之比较,就会被决定使用在原先资料次序中的条目,当作一个同分决赛。然而,要记住这种次序通常牵涉到额外的空间负担。
排列算法列表
在这个表格中,n是要被排序的纪录数量以及k是不同键值的数量。
稳定的
冒泡排序(bubble sort) — O(n2)
鸡尾酒排序 (Cocktail sort, 双向的冒泡排序) — O(n2)
插入排序 (insertion sort)— O(n2)
桶排序 (bucket sort)— O(n); 需要 O(k) 额外 记忆体
计数排序 (counting sort) — O(n+k); 需要 O(n+k) 额外 记忆体
归并排序 (merge sort)— O(n log n); 需要 O(n) 额外记忆体
原地归并排序 — O(n2)
二叉树排序 (Binary tree sort) — O(n log n); 需要 O(n) 额外记忆体
鸽巢排序 (Pigeonhole sort) — O(n+k); 需要 O(k) 额外记忆体
基数排序 (radix sort)— O(n·k); 需要 O(n) 额外记忆体
Gnome sort — O(n2)
Library sort — O(n log n) with high probability, 需要 (1+ε)n 额外记忆体
不稳定
选择排序 (selection sort)— O(n2)
希尔排序 (shell sort)— O(n log n) 如果使用最佳的现在版本
Comb sort — O(n log n)
堆排序 (heapsort)— O(n log n)
Smoothsort — O(n log n)
快速排序 (quicksort)— O(n log n) 期望时间, O(n2) 最坏情况; 对于大的、乱数串行一般相信是最快的已知排序
Introsort — O(n log n)
Patience sorting — O(n log n + k) 最外情况时间, 需要 额外的 O(n + k) 空间, 也需要找到最长的递增子序列(longest increasing subsequence)
不实用的排序算法
Bogo排序 — O(n × n!) 期望时间, 无穷的最坏情况。
Stupid sort — O(n3); 递回版本需要 O(n2) 额外记忆体
Bead sort — O(n) or O(√n), 但需要特别的硬体
Pancake sorting — O(n), 但需要特别的硬体
排序的算法
排序的算法有很多,对空间的要求及其时间效率也不尽相同。下面列出了一些常见的排序算法。这里面插入排序和冒泡排序又被称作简单排序,他们对空间的要求不高,但是时间效率却不稳定;而后面三种排序相对于简单排序对空间的要求稍高一点,但时间效率却能稳定在很高的水平。基数排序是针对关键字在一个较小范围内的排序算法。
插入排序
冒泡排序
选择排序
快速排序
堆排序
归并排序
基数排序
希尔排序
插入排序
插入排序是这样实现的:
首先新建一个空列表,用于保存已排序的有序数列(我们称之为"有序列表")。
从原数列中取出一个数,将其插入"有序列表"中,使其仍旧保持有序状态。
重复2号步骤,直至原数列为空。
插入排序的平均时间复杂度为平方级的,效率不高,但是容易实现。它借助了"逐步扩大成果"的思想,使有序列表的长度逐渐增加,直至其长度等于原列表的长度。
冒泡排序
冒泡排序是这样实现的:
首先将所有待排序的数字放入工作列表中。
从列表的第一个数字到倒数第二个数字,逐个检查:若某一位上的数字大于他的下一位,则将它与它的下一位交换。
重复2号步骤,直至再也不能交换。
冒泡排序的平均时间复杂度与插入排序相同,也是平方级的,但也是非常容易实现的算法。
选择排序
选择排序是这样实现的:
设数组内存放了n个待排数字,数组下标从1开始,到n结束。
i=1
从数组的第i个元素开始到第n个元素,寻找最小的元素。
将上一步找到的最小元素和第i位元素交换。
如果i=n-1算法结束,否则回到第3步
选择排序的平均时间复杂度也是O(n²)的。
快速排序
现在开始,我们要接触高效排序算法了。实践证明,快速排序是所有排序算法中最高效的一种。它采用了分治的思想:先保证列表的前半部分都小于后半部分,然后分别对前半部分和后半部分排序,这样整个列表就有序了。这是一种先进的思想,也是它高效的原因。因为在排序算法中,算法的高效与否与列表中数字间的比较次数有直接的关系,而"保证列表的前半部分都小于后半部分"就使得前半部分的任何一个数从此以后都不再跟后半部分的数进行比较了,大大减少了数字间不必要的比较。但查找数据得另当别论了。
堆排序
堆排序与前面的算法都不同,它是这样的:
首先新建一个空列表,作用与插入排序中的"有序列表"相同。
找到数列中最大的数字,将其加在"有序列表"的末尾,并将其从原数列中删除。
重复2号步骤,直至原数列为空。
堆排序的平均时间复杂度为nlogn,效率高(因为有堆这种数据结构以及它奇妙的特征,使得"找到数列中最大的数字"这样的操作只需要O(1)的时间复杂度,维护需要logn的时间复杂度),但是实现相对复杂(可以说是这里7种算法中比较难实现的)。
看起来似乎堆排序与插入排序有些相像,但他们其实是本质不同的算法。至少,他们的时间复杂度差了一个数量级,一个是平方级的,一个是对数级的。
平均时间复杂度
插入排序 O(n2)
冒泡排序 O(n2)
选择排序 O(n2)
快速排序 O(n log n)
堆排序 O(n log n)
归并排序 O(n log n)
基数排序 O(n)
希尔排序 O(n1.25)
冒泡排序
654
比如说这个,我想让它从小到大排序,怎么做呢?
第一步:6跟5比,发现比它大,则交换。564
第二步:5跟4比,发现比它大,则交换。465
第三步:6跟5比,发现比它大,则交换。456

热点内容
汽修汽配源码 发布:2025-05-14 20:08:53 浏览:742
蜜蜂编程官网 发布:2025-05-14 19:59:28 浏览:57
优酷怎么给视频加密 发布:2025-05-14 19:31:34 浏览:635
梦三国2副本脚本 发布:2025-05-14 19:29:58 浏览:860
phpxmlhttp 发布:2025-05-14 19:29:58 浏览:434
Pua脚本 发布:2025-05-14 19:24:56 浏览:449
苹果像素低为什么比安卓好 发布:2025-05-14 19:13:23 浏览:461
安卓机微信怎么设置红包提醒 发布:2025-05-14 19:00:15 浏览:272
androidsystem权限设置 发布:2025-05-14 18:56:02 浏览:971
mq脚本 发布:2025-05-14 18:45:37 浏览:25