#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define N 10000
/*直接插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,
按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。
设数组为a[0…n-1]。
1.初始时,a[0]自成1个有序区,无序区为a[1..n-1]。令i=1
2.将a[i]并入当前的有序区a[0…i-1]中形成a[0…i]的有序区间。
3.i++并重复第二步直到i==n-1。排序完成。*/
void InsertSort1(int arr[],int n)//插入排序1
{
int i,j,k,temp;
for(i=1;i<n;i++)
{
for(j=i-1;j>=0;j--)
if(arr[j]<arr[i])
break;
if(j!=i-1)
{
temp=arr[i];
for(k=i;k>j;k--)
arr[k]=arr[k-1];
arr[j+1]=temp;
}
}
}
void InsertSort2(int arr[],int n)//插入排序2
{
int i,j,temp;
for(i=1;i<n;i++)
{
if(arr[i]<arr[i-1])
{
temp=arr[i];
for(j=i-1;j>=0&&arr[j]>=temp;j--)
arr[j+1]=arr[j];
arr[j+1]=temp;
}
}
}
int Swap(int a,int b)
{
return 0;
}
void Insertsort3(int a[], int n)//插入排序3
{
int i, j;
for (i = 1; i < n; i++)
for (j = i - 1; j >= 0 && a[j] > a[j + 1]; j--)
Swap(a[j], a[j + 1]);
}
/*希尔排序的实质就是分组插入排序,该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。
该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)
分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,
再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),
效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。*/
void ShellSort1(int arr[],int n)
{
int i,j,k,gap,temp;
for(gap=n/2;gap>0;gap/=2)
{
for(i=0;i<gap;i++)
{
for(j=i+gap;j<n;j+=gap)
{
if(arr[j]<arr[j-gap])
{
temp=arr[j];
k=j-gap;
while(k>=0&&arr[k]>temp)
{
arr[k+gap]=arr[k];
k-=gap;
}
arr[k+gap]=temp;
}
}
}
}
}
/*快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。
它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod)。
该方法的基本思想是:
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。*/
int AdjustArray(int arr[],int l,int r)
{
int i=l,j=r;
int x=arr[i];
while(i<j)
{
while(i<j&&arr[j]>x)
j--;
if(i<j)
arr[i]=arr[j],i+=1;
while(i<j&&arr[i]<=x)
i++;
if(i<j)
arr[j]=arr[i],j--;
arr[i]=x;
}
return i;
}
int QuickSort(int arr[],int l,int r)
{
int i;
if(l<r)
{
i=AdjustArray(arr,l,r);
QuickSort(arr,l,i-1);
QuickSort(arr,i+1,r);
}
return 1;
}
/*
快排cmp函数*/
int cmp(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
/*
一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2。它的左右子结点下标分别为
2 * i + 1和2 * i + 2。如第0个结点左右子结点下标分别为1和2。
每次插入都是将新数据放在数组最后。可以发现从这个新数据的父结点到根结点必然为一个有序的数列,
现在的任务是将这个新数据插入到这个有序数据中——这就类似于直接插入排序中将一个数据并入到有序区间中
*/
void MinHeapFixup(int a[],int i) //新加入i节点,其父节点为(i-1)/2
{
int j,temp;
temp=a[i];
j=(i-1)/2; //父节点
while(j>=0&&i!=0)
{
if(a[j]<=temp)
break;
a[i]=a[j]; //把较大的节点下移,替换其他的子节点
i=j;
j=(i-1)/2;
}
a[i]=temp;
}
void MinHeapAddNumber(int a[],int n,int nNum)
{
a[n]=nNum;
MinHeapFixup(a,n);
}
void MinHeapFixdown(int a[],int i,int n)
{
int j,temp;
j=2*i+1;
temp=a[i];
while(j<n)
{
if(j+1<n&&a[j+1]<a[j]) //两个孩子节点中选取最小的孩子节点
j++;
if(a[j]>=temp)
break;
a[i]=a[j];
i=j;
j=2*i+1;
}
a[i]=temp;
}
void MinHeapDeleteNumber(int a[], int n)
{
Swap(a[0], a[n - 1]);
MinHeapFixdown(a, 0, n - 1);
} //在最小堆中删除数
void MakeMinHeap(int a[],int n)//排序,建立最小堆
{
int i;
for(i=n/2-1;i>=0;i--)
MinHeapFixdown(a,i,n);
}
int main()
{
int arr1[N],arr2[N],i;
int arr3[N],arr4[N],arr[7]={10,15,56,25,30,70},arr5[10]={9,12,17,30,50,20,60,65,4,49};
for(i=0;i<N;i++)
{
arr1[i]=arr2[i]=arr3[i]=arr4[i]=rand();
}
MakeMinHeap(arr5,10);
for(i=0;i<10;i++)
{
printf("%d ",arr5[i]);
}
/*
MinHeapAddNumber(arr,6,2);
for(i=0;i<7;i++)
printf("%d ",arr[i]);*/
//clock_t begin,end;
/*
begin=clock();
InsertSort1(arr1,N);
end=clock();
printf("ZC:%d\n",end-begin);
begin=clock();
ShellSort1(arr2,N);
end=clock();
printf("shell\:%d\n",end-begin);
begin=clock();
QuickSort(arr3,0,N-1);
end=clock();
printf("QC:%d\n",end-begin);
begin=clock();
qsort(arr4,N,sizeof(int),cmp);
end=clock();
printf("qsort:%d\n",end-begin);
*/
return 0;
}