目录:冒泡,选择,插入,希尔,归并,快排 以及 堆排
一、冒泡
1.经典排序
for(i=0;i<n-1;i++)
{
int flag=1;
for(j=0;j<n-i-1;j++)
if(a[j]>a[j+1])
{
int t=a[j+1];
a[j+1]=a[j];
a[j]=t;
flag=0;
}
if(flag)
break;
}
2.简化版
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
if(a[i]>a[j])
{
int t=a[i];
a[i]=a[j];
a[j]=t;
}
二、选择排序
for(i=0;i<n;i++)
{
int min=i;
for(j=i+1;j<n;j++)
if(a[min]>a[j])
min=j;
if(min!=i)
{
int t;
t=a[i];
a[i]=a[min];
a[min]=t;
}
}
三、插入排序
for(i=0;i<n;i++)
{
int temp = a[i];//必须有,这就是防覆盖的关键
for(j=i;j>0;j--)
{
if(temp < a[j-1])
a[j] = a[j-1]; //将所有在nums[i]之前的大于nums[i]的值都往后移一位
else
break;
}
a[j] = temp;
}
四、希尔排序
for(incre=n/2;incre>0;incre/=2)//步长
{
for(i=incre;i<n;i++)//列的开始
{
int t=a[i];
for(j=i;j>=incre;j-=incre)//那一列中的元素
{
if(t<a[j-incre])
a[j]=a[j-incre];
else
break;
}
a[j]=t;
}
}
五、归并排序 MergeSort
void sort(int a[],int low,int high)//将数组分为2部分
{
if(low<high)
{
int mid=(low+high)/2;
sort(a,low,mid);
sort(a,mid+1,high);
merge(a,low,mid,high);
}
}
void merge(int a[],int low,int mid,int high)//将上面分成的二部分进行排序(合并)
{
int i=low,j=mid+1;
int b[n],k=0;
while(i<=mid&&j<=high)
{
if(a[i]>a[j])
b[k++]=a[j++];
else
b[k++]=a[i++];
}
while(j<=high)
b[k++]=a[j++];
while(i<=mid)
b[k++]=a[i++];
for(i=0;i<=high-low;i++)
a[i+low]=b[i];
}
六、快速排序 QuickSort
缺陷:给出二元数组a[MAXN][2],按第一个关键值从小到大排序后输出,要求第一关键值相同情况下不改变原数组次序
例如:二元 (1,0),(1,2)排序后改变位置。
void Qsort(int nums[],int left,int right)
{
if(left>right)
return ;
int i=left,j=right,pivot=nums[left];
while(i<j)
{
while(i<j&&nums[j]>=pivot)//保证基准右边的大于他,由于基准为left,所以先看右边的,也就是j
j--;
nums[i]=nums[j];
while(i<j&&nums[i]<=pivot)//保证基准左边的小于他
i++;
nums[j]=nums[i];
}//以基准为界,左小右大
nums[i]=pivot;
Qsort(nums,left,i-1);//左边继续
Qsort(nums,i+1,right);//右边再来
}
七、堆排序 HeapSort
void percDown(int nums[],int i,int size)//最大堆
{
int left = 2*i+1;
int right = 2*i+2;
int max = i;
if(left < size && nums[left] > nums[max])
max = left;
if(right < size && nums[right] > nums[max])
max = right;
if(max != i)
{
int temp = nums[i];
nums[i] = nums[max];
nums[max] = temp;
percDown(nums,max,size);
}
}
void HeapSort(int nums[],int len)
{
int i;
for(i=len/2;i>=0;i--)//构建最大堆,从叶子向root开始建立,所以只考虑孩子(我们建立的就是parent且下级为最大堆)
percDown(nums,0,len);
for( i=len-1;i>=1;i--)//循环,每次把根节点和最后一个节点调换位置
{
int temp = nums[0];
nums[0] = nums[i];
nums[i] = temp;
percDown(nums,0,i);//0,即全部调整,i树的范围,每次将最大放到最后,size缩小
}
}