排序

来源:互联网 发布:网络推广主要做什么 编辑:程序博客网 时间:2024/04/27 06:44

一,什么是排序?

  排序是计算机内经常进行的一种操作,其目的是将一组"无序"的记录序列调整为"有序"的记录序列

排序的定义

假设含n个记录的序列为{ R1, R2, …, Rn }其相应的关键字序列为 { K1, K2, …,Kn }这些关键字相互之间可以进行比较,即在它们之间存在着这样一个关系 :Kp1≤Kp2≤…≤Kpn按此固有关系将上式记录序列重新排列为{ Rp1, Rp2, …,Rpn }的操作称作排序。

二,内部排序和外部排序

若整个排序过程不需要访问外存便能完成,则称此类排序问题为"内部排序";反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为"外部排序"
排序方法还可分为"稳定的排序""不稳定的排序"
#define MAXSIZE 1000//待排序的记录数目typedef int KeyType;//关键字类型为整数类型typedef struct{  KeyType key;//关键字项  InfoType otherinfo;//其他数据项}RecordType;//记录类型typedef struct{  RecordType r[MAXSIZE+1];  int length;//序列长度,即记录个数}RecordList;//记录序列类型,及顺序表类型RecordList L;

插入类排序

直接插入排序

这里写图片描述
这里写图片描述

直接插入排序举例:48 62 35 77 55 14 *35 98-48 -62 35 77 55 14 *35 98-35 -48 -62 77 55 14 *35 98-35 -48 -62 -77 55 14 *35 98-35 -48 -55 -62 -77 14 *35 98-14 -35 -48 -55 -62 -77 *35 98-14 -35 -*35 -48 -55 -62 -77 98-14 -35 -*35 -48 -55 -62 -77 -98
//直接插入排序void InsertSort(RecordType r[],int length){  int i,j;  for(i=2;i<=length;i++)  {    r[0]=r[i];/*将待插入记录存放到监视哨r[0]中*/    j=i-1;    while(r[0].key<r[j].key)/*寻找插如位置*/    {      r[j+1]=r[j];      j=j-1;    }    r[j+1]=r[0];/*将待插入记录插入到已排序的序列中*/  }}

折半插入排序

void BinSort(RecordType r[],int length){  int i,j;  RecordType x;  int low,high,mid;  for(i=2;i<=length;i++)  {    x=r[i];    low=1;    high=i-1;    while(low<=high)/*确定插入位置*/    {      mid=(low+high)/2;      if(x.key<r[mid].key)        high=mid-1;      else        low=mid+1;    }    for(j=i-1;j>=low;j--)      r[j+1]=r[j];/* 记录依次向后移动 */    r[low]=x;/* 插入记录 */  }}

希尔排序

这里写图片描述

void ShellInsert(RecordType r[], int length, int delta) {   int i,j; //希尔排序  for(i=1+delta;i<= length; i++)  if(r[i].key < r[i-delta].key)  {      r[0]= r[i];     for(j=i-delta; j>0 &&r[0].key < r[j].key; j-=delta)         r[j+delta]= r[j];     r[j+delta]= r[0];   }}void ShellSort(RecordType r[], int length, int delt[], int n){   int i;  for(i=0 ; i<=n-1; ++i)     ShellInsert(r, length, delt[i]);}

这里写图片描述
这里写图片描述
这里写图片描述

交换类排序

冒泡排序

//一个记录序列的关键字分别为46,25,68,33,*33,19,12,80第一趟:25 46 33 *33 19 12 68 80第二趟:25 33 *33 19 12 46 68 80第三趟:25 33 19 12 *33 46 68 80第四趟:25 19 12 33 *33 46 68 80第五趟:19 12 25 33 *33 46 68 80第六趟:12 19 25 33 *33 46 68 80第七趟:12 19 25 33 *33 46 68 80
//冒泡排序void BubbleSort(RecordList L){  flag=1;  for(i=1;i<=L.length-1 && flag;i++)  {    flag=0;    for(j=1;j<=L.length-i;j++)    {      if(L.r[j].key>L.r[j+1].key)      {        t=L.r[j];        L.r[j]=L.r[j+1];        L.r[j+1]=t;        flag=1;      }    }  }}

快速排序

目标:找一个记录,以它的关键字作为“枢轴”,凡其关键字小于枢轴的记录均移动至该记录之前,反之,凡关键字大于枢轴的记录均移动至该记录之后。致使一趟排序之后,记录的无序序列R[s..t]将分割成两部分R[s..i-1]R[i+1..t],且R[j].keyR[i].keyR[j].key(sji-1) 枢轴 (i+1≤jt)。

一趟快速排序过程
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

据结构 第九章 排序一趟快速排序int QKPass(RecordType r[],int left,int right){   RecordType x; int low,high; x= r[left];  low=left;   high=right;  while ( low<high )  {     while (low< high && r[high].key>=x.key )    high--;    if ( low <high )    {        r[low]= r[high]; low++;     }    while (low<high && r[low].key<x.key )       low++;    if ( low<high ) /* 找到大于x.key的记录,则交换*/    {       r[high]= r[low]; high--;     }  }  r[low]=x; /*将基准记录保存到low=high的位置*/  return low; /*返回基准记录的位置*/}void QKSort(RecordType r[],int low, int high ){   int pos;  if(low<high)  {     pos=QKPass(r, low, high);     /*将枢轴元素为界划分两个子表*/     QKSort(r, low, pos-1); /*对左部子表快速排序*/     QKSort(r, pos+1, high); /*对右部子表快速排序*/  }}

这里写图片描述
这里写图片描述
这里写图片描述

选择类排序

简单选择排序

这里写图片描述

void SelectSort(RecordType r[], int length){    int i,j,k;    int n;    RecordType x;    n=length;   for ( i=1 ; i<= n-1; ++i)   {       k=i;     for ( j=i+1 ; j<= n ; ++j)        if (r[j].key < r[k].key )            k=j;     if ( k!=i) /* 进行记录的交换*/     {        x= r[i];       r[i]= r[k];       r[k]=x;     }   }}

时间复杂度:对n个记录进行简单选择排序,所需进行的关键字间的比较次数总计为这里写图片描述
空间复杂度:需要一个辅助空间用于交换,故为O(1)
稳定性:不稳定

树形选择排序

这里写图片描述
12 19 25 33 33 46 68 80
这里写图片描述

堆排序

这里写图片描述
堆的筛选
这里写图片描述
**一个记录序列的关键字为46,12,33,72,68,19,80,33,建立初始堆
这里写图片描述

归并排序

二路归并排序

这里写图片描述

void Merge(RecordType r1[], int low, int mid,int high, RecordType r2[]){   int i,j,k;   i=low;   j=mid+1;     k=low;  while ( (i<=mid)&&(j<=high) )  {     if ( r1[i].key<=r1[j].key )    {        r2[k]=r1[i];        ++i;     }    else    {        r2[k]=r1[j];        ++j;     }    ++k;  }  while( i<=mid )  {     r2[k]=r1[i];     k++;     i++;   }  while( j<=high)  {     r2[k]=r1[j];     k++;     j++;   }}

这里写图片描述

分配类排序

基数排序

这里写图片描述
这里写图片描述
这里写图片描述

各种排序方法综合比较

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

0 0
原创粉丝点击