常用的7中排序算法源码

来源:互联网 发布:织梦dedecms视频 编辑:程序博客网 时间:2024/06/05 09:28

#include<stdio.h>
#include<stdlib.h>

int a[]={55,60,40,10,80,65,15,5,75};
int n=9;

void Swap(int &x,int& y)
{
 int t=x;
 x=y;
 y=t;
}

void Print(int a[],int n)
{
 for(int i=0;i<n;i++)
  printf("%d ",a[i]);
 printf("\n");
}


void BubbleSort(int a[],int n)   //冒泡排序
{
 int i,j;
 for( i=0;i<n-1;i++)//外层循环尾n-1趟
  for( j=0;j<n-1-i;j++)//注意j结束的条件
   if(a[j]>a[j+1])
    Swap(a[j],a[j+1]);
}

//a[s..m]中,除了data[s]外,其余元素均满足堆的定义
void HeapAdjust(int a[],int s,int m)
{
 int t=a[s];     //t保存待调整的值
 for(int j=s*2+1;j<=m;j=j*2+1)
 {
  if(j<m&&a[j]<a[j+1])j++;//j为值较大的孩子的下标
  if(t>=a[j])    //如果当前节点的值已经比两个孩子的值大,则不用调整
   break;
  a[s]=a[j];    //当前节点的值等于其“大”孩子的值
  s=j;     //并且,当前节点为原来”当前节点“的”大“孩子
 }
 a[s]=t;      //这个节点有可能是叶子节点即没有孩子,或者”t保存待调整的值“比两个孩子都大
}

void HeapSort(int a[],int n)
{
 for(int i=n/2-1;i>=0;i--) //因为大于n/2-1的节点均是叶子节点,没有孩子,即已经是大顶堆。所以只要从n/2-1开始
  HeapAdjust(a,i,n-1);
 for(int j=n-1;j>=0;j--)  //将最大值放到最后一个位置,从新把a[0..n-2]调整为大顶堆,再继续。
 {
  int t=a[0];
  a[0]=a[j];
  a[j]=t;
  HeapAdjust(a,0,j-1);
 }
}

void QuickSort(int a[],int low,int high)
{
 if(low<high)
 {
  int i=low,j=high;

int k=rand()%(high-low)+low;

Swap(a[low],a[k]);
  int povitkey=a[low];    //选择第一个元素为枢轴
  while(i<j)       //从后向前扫描,比枢轴小的元素放到左边
  {
   while(i<j&&a[j]>=povitkey)--j;
   if(i<j)
    a[i++]=a[j];
   while(i<j&&a[i]<=povitkey)++i;//从前往后扫描,比枢轴大的元素放到右边
   if(i<j)
    a[j--]=a[i];
  }
  a[i]=povitkey;     //此时,i==j,把枢轴放好,再对左右两边分别快排
  QuickSort(a,low,i-1);
  QuickSort(a,i+1,high);
 }
}


QuickSort的另一种写法:

void RandomizedQuickSort(int a[],int p,int r)

{

if(p<r)

{

int q=RandomizedPartition(a,p,r);

RandomizedQuickSort(a,p,q-1);

RandomizedQuickSort(a,q+1,r);

}

}


int RandomizedPartition(int a[],int p,int r)

{

int k=rand()%(r-p+1)+p;

Swap(a[p],a[k]);

int i=p;

int j=r+1;

int x=a[p];

while(true)

{

while(a[++i]<x&&i<r);

while(a[--j]>x);

if(i>=j)

break;

Swap(a[i],a[j]);

}

a[p]=a[j];

a[j]=x;

return j;

}



void SelectSort(int a[],int n)   //选择排序
{
 for(int i=0;i<n-1;i++)
 {
  int k=i;
  for(int j=i+1;j<n;j++)
   if(a[j]<a[k])
    k=j;
  if(k!=i)
   Swap(a[k],a[i]);
 }
}

void InsertSort(int a[],int n)
{
 for(int i=1;i<n;i++)    //注意:从1开始,因为第0个元素已经有序了
 {
  int t=a[i];
  int j;
  for( j=i;j>0&&t<a[j-1];j--)
   a[j]=a[j-1];
  a[j]=t;
 }
}

void ShellSort(int a[],int n)
{
 int *delta=(int *)malloc(sizeof(int)*(n/2));  //注意delta数组大小
 int k=n;
 int i=0;
 do
 {
  k=k/2;
  delta[i++]=k;
 }while(k>0);
 i=0;
 int dk,j;
 while((dk=delta[i])>0)    //注意循环条件
 {
  for(k=delta[i];k<n;k++)   //从k=delta[i]开始直到最后,进行类似”插入“排序
  {
   if(a[k]<a[k-dk])
   {
    int t=a[k];
    for( j=k;j>=0&&t<a[j-dk];j-=dk)
     a[j]=a[j-dk];
    a[j]=t;
   }
  }
  i++;
 }
 free(delta);
}

void Merge(int a[],int m,int s,int n)  //用while循环,看着省事点
{
 int b[10];      //注意此处用的是动态数组,用malloc开辟的好像有问题。。
 int i=m,j=s+1,k=m;
 while(i<=s&&j<=n)
  if(a[i]<=a[j])    //此处决定是否”稳定“
   b[k++]=a[i++];
  else
   b[k++]=a[j++];
 while(i<=s)
  b[k++]=a[i++];
 while(j<=n)
  b[k++]=a[j++];
 for(i=m;i<=n;i++)
  a[i]=b[i];
}

void MSort(int a[],int m,int n)
{
 if(m<n)
 {
  int k=(m+n)/2;
  MSort(a,m,k);    //中间一分为二,两边分别排,然后归并
  MSort(a,k+1,n);
  Merge(a,m,k,n);
 }
}

void MergeSort(int a[],int n)
{
 MSort(a,0,n-1);
}


int main()
{
 Print(a,n);
 BubbleSort(a,n);
 HeapSort(a,n);
 QuickSort(a,0,n-1);
 SelectSort(a,n);
 InsertSort(a,n);
 ShellSort(a,n);
 MergeSort(a,n);
 Print(a,n);
 return 0;
}

 

原创粉丝点击