几种排序方法

#if 0//1,1直接插入排序
void insertSort(int a[]);
int main()
{
 int a[]={49,38,65,97,76,13,27};
 int i;
 for (i=0; i<7; ++i)
     printf("%d ",a[i]);
 printf("\n");
 insertSort(a);
 for (i=0; i<7; ++i)
     printf("%d ",a[i]);
 printf("\n");
 return 0;
}
void insertSort(int a[])
{
 int i,j,t;
 for (i=1; i<7; ++i)// 初始的时候认为a[0]是有序的,其余为无序子序列。
 {
  for (j=i; j>0; --j)//从后面依次取元素往有序的序列里面插入数据,
   if (a[j]<a[j-1])  //用遍历的方法找到应该插入的位置,每次都交换数据
   {
    t=a[j];
    a[j]=a[j-1];
    a[j-1]=t;
   }
 }
}
#endif
#if 0 //1.2直接插入排序(加入哨兵)
void insertSort(int a[]);
int main()
{
 int a[]={0,49,38,65,97,76,13,27};
 int i;
 for (i=1; i<8; ++i)
     printf("%d ",a[i]);
 printf("\n");
 insertSort(a);
 for (i=1; i<8; ++i)
     printf("%d ",a[i]);
 printf("\n");
 return 0;
}
void insertSort(int a[])
{
 int i,j,k;
 for (i=2; i<8; ++i) //初始时认为a[1]是有序序列,其余为无序序列。
   if (a[i]<a[i-1]) //如果插入数据小于最后一个关键字,则
      {
       a[0]=a[i];  //先将插入的关键字复制为哨兵
       a[i]=a[i-1]; //将有序的序列最后一个数据后移一位
      for (j=i-2; j>0&&a[0]<a[j]; --j)//一边比较一边后移
          a[j+1]=a[j]; //将有序序列中大于哨兵的的部分整体后移一位
      a[j+1]=a[0];  //找到合适的位置,插入哨兵
      }
}
#endif
#if 0
void BinsertSort(int a[]);
int main()
{
 int a[]={0,49,38,65,97,76,13,27};
 int i;
 for (i=1; i<8; ++i)
     printf("%d ",a[i]);
 printf("\n");
 BinsertSort(a);
 for (i=1; i<8; ++i)
     printf("%d ",a[i]);
 printf("\n");
 return 0;
}
void BinsertSort(int a[]) //折半查找也是在加入哨兵的基础上对有序数列进行这般法查找
{
 int low,high,m,i,j;
 for (i=2; i<8; ++i) //初始时认为a[1]是有序序列,其余为无序序列。
 {
  a[0]=a[i];     //先将插入的关键字复制为哨兵
  low=1;high=i-1;
  while (low <= high) //用折半查找的方法来确定插入数据在有序序列中应该插入的位置
  {
   m=(low+high)/2;
   if (a[0]<a[m])
       high=m-1;
   else
       low=m+1;
  }
  for (j=i-1; j>= high+1; --j)  //将有序序列中大于插入数据的都后移一位
      a[j+1]=a[j];
  a[j+1]=a[0]; //将插入的数据放入合适的位置
 }
}
#endif
#if 0 //归并排序
void remsort(int a[],int b[],int left,int right);
void merge(int a[],int b[],int left,int mid,int right);
int main()
{
 int a[]={49,38,65,97,76,13,27,49};
 int b[20];
 int left,right,i;
 left=0;
 right=6;
 for (i=0; i<7; ++i)
     printf("%d ",a[i]);
 printf("\n");
 remsort(a,b,left,right);
 for (i=0; i<7; ++i)
     printf("%d ",a[i]);
 printf("\n");
 return 0;
}
void remsort(int a[],int b[],int left,int right)
{
 int mid=(left+right)/2; //将原记录序列平分成两部分,
 if (left>=right)  //当只有一个数据的时候,本身就是有序的,作为递归终止的条件
     return ;
 remsort(a,b,left,mid); //递归的将左边的部分进行排序,
 remsort(a,b,mid+1,right); //递归的将右边的序列进行排序,
 merge(a,b,left,mid,right); //将两个有序的序列合并成一个新的序列a
}
void merge(int a[],int b[],int left,int mid,int right)
{
 int i;
 int s1,s2,k;
 for (i=left; i <= right; ++i) //将a里面的数据先保存到b里面去。
     b[i]=a[i];
 s1=left; //用s1来记录首个元素
 s2=mid+1;//用s2来记录第二部分首个元素
 k=left; //用k来初始化位置
 while (s1<=mid&& s2<= right) //用while循环将两个部分进行合并 并排序
 {
  if (b[s1]<=b[s2])
      a[k++]=b[s1++];
  else
      a[k++]=b[s2++];
 }
 while (s1<=mid)    //如果有剩余元素没有排进去的,用while 循环依次赋值进去
     a[k++]=b[s1++];
 while (s2<=right)
     a[k++]=b[s2++];
}
#endif
#if 0//快速排序是对冒泡法的改进
int quicksort(int a[],int left,int right);
void Qsort(int a[],int left,int right);
int main()
{
 int a[]={49,38,65,97,76,13,27,49};
 int left,right,i;
 left=0;
 right=6;
 for (i=0; i<7; ++i)
     printf("%d ",a[i]);
 printf("\n");
 Qsort(a,left,right);
 for (i=0; i<7; ++i)
     printf("%d ",a[i]);
 printf("\n");
 return 0;
}
void Qsort(int a[],int left,int right)
{
    int p; //用以标志枢轴的位置
 if (left <right)
 {
  p=quicksort(a,left,right); //确定列表L中枢轴的最终位置
  Qsort(a,left,p-1); //对枢轴左部的子列表进一步划分
  Qsort(a,p+1,right); //对枢轴右部的子列表进一步划分
 }
}
int quicksort(int a[],int left,int right)
{
 int k;
 k=a[left]; //用k来保存每次的关键字,为了减少交换的次数,将关键字先保存,等循环结束,也就是确定
            //最终位置的时候,再将其移过去。
 while (left<right) //当left=right的时候,就确定了枢轴的最终位置,
 {
  while (left <right&&a[right]>=k) //向左移动right,越过不小于枢轴的记录,到达第一个小于枢轴的记录,
      right--;    //
   a[left]=a[right];  //将小于枢轴的记录与枢轴“想交换”
   while (left <right&&a[left]<=k) //向右移动left,越过小于枢轴的记录,到达第一个不比枢轴小的记录,
       left++;   //将不小于枢轴的记录与与枢轴交换
   a[right]=a[left];
 }
 a[left]=k; //确定了枢轴最终位置,可以将其移过来
 return left; //返回枢轴最终位置
}
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值