#include<stdio.h>
#include<malloc.h>
void Swap(int *a, int*b)
{
int mid=*a;
*a=*b;
*b=mid;
}
///冒泡算法
void Bubble_Sort(int *A,int n)
{
int Havedone;
for(int i=1;i<n;i++) // n个数要进行N-1次排序
{
Havedone=1;
for(int j=0;j<n-i;j++)//第i 次排序时,数组末端i-1个数是排好的了
{
if(A[j]>A[j+1])
{
Havedone=0;
Swap(&A[j],&A[j+1]);
}
}
if(Havedone)
return;
}
}
//选择排序。第i次选择第i大的数放到一边。
void Choose_Sort(int *A,int n)
{
int min,temp;
for(int i=0;i<n-1;i++) //共进行n-1次选择
{
min=A[i]; //第i小的值要放到一边
temp=-1;
for(int j=i+1;j<n;j++)
if(min>A[j])
{
min=A[j];
temp=j;
}
if(temp!=-1)
Swap(&A[i],&A[temp]);
}
}
//快速排序
void Quick_Sort(int *A,int low,int high)
{
if(high-low<=1)
return;
int mid;
int KeyWord=A[low]; //取左起第一个元素为基元素
int left=low; //左指针右移
int right=high; //右指针左移
while(left<right) //左指针越过右指针即遍历全部元素
{
while(left<=right && A[left] <KeyWord) //找啊找,找到左边的一个比基元素还要大的
left++;
while(left<=right && A[right]>KeyWord) //右边一个比之少的
right--;
if(left<right) //左边大的和右边小的交换
Swap(&A[left],&A[right]);
}
//跳出循环后,数组 变为 基元素小小小小小大大大大大 这样
if(A[low]>A[right])
Swap(&A[low],&A[right]); //把基元素放在中间
Quick_Sort(A,low,right-1);
Quick_Sort(A,right+1,high);
}
//堆排序
//调整元素位置,使数组重新具有堆的结构
void AbjustHeap(int *A,int n,int k)//n 元素个数,k可能要调整元素位置
{
int rchild,lchild,maxchild;
maxchild=lchild=k*2;
rchild=lchild+1;
if(maxchild>n) // 已经是叶子结点
return;
if(rchild<=n && A[lchild]<A[rchild])
maxchild=rchild;
if(A[maxchild]>A[k]) //父结点小于儿子交换
{
Swap(&A[maxchild],&A[k]);
AbjustHeap(A,n,maxchild); //交换后可能会破坏堆性质,重新调整(递归)
}
}
//建立堆的实质就是调整数组中元素位置
void BuildHeap(int *A,int n)
{
for(int father=n/2;father>=1;father--)
{
AbjustHeap(A,n,father);//从最后一个父结点开始
}
}
//堆排序实质就是从建好的堆中交换最大元素,然后调整
void HeapSort(int *A,int n)
{
BuildHeap(A,n);
for(int times=n; times>1;times--)
{
Swap(&A[times],&A[1]); //最大元素置末端
AbjustHeap(A,times-1,1); //数组规范减1
}
}
//归并排序
//合并算法,将两个有序子数组归并为一个数组
//start 表示数组开始位置,END为最末位置,SCALe为归并规模
void Merge(int *A,int start,int end,int scale)
{
int *p=(int *)malloc(sizeof(int)*(end-start+1));
int i,j;
i=start; //i指针为上数组位置
j=start+scale; //j为下数组位置
int middle=j; //i指针不可能达到下数组开始的位置
int time=0;
while(i<middle&&j<=end) // 逐一比较
{
if(A[i]<A[j])
p[time++]=A[i++];
else
p[time++]=A[j++];
}
if(i==middle) //余下的数组无需比较
{
while(j<=end)
p[time++]=A[j++];
}
else
{
while(i<middle)
p[time++]=A[i++];
}
while(time>0)
{
A[end--]=p[--time];
}
free(p);
p=NULL;
}
//归并排序就是逐渐扩大合并规模
void MergeSort(int *A,int n)
{
int scale=1; //归并的规模
int start; //开始数组归并的位置
int end; //完成一次合并的末位置
while(scale<n)
{
start=0;
end=start+scale*2-1;
while(end<n)
{
Merge(A,start,end,scale); //显然一般有end =start +scale*2-1
start=end+1;
end=start+scale*2-1;
}
if(start<n)
Merge(A,start,n,scale);
scale=scale*2;
}
}
int main()
{
int num[32]={15,16,26,17,18,25,27,1,2,9,28,29,19,20,21,22,23,24,30,31,32,10,11,12,13,3,4,5,6,7,8,14};//测试数据
// Bubble_Sort(num,32);
// Choose_Sort(num,32);
// Quick_Sort(num,0,31);
// HeapSort(num,31);
MergeSort(num,31);
for(int i=0;i<32;i++)
printf("%d ",num[i]);
}
几种常见的排序
最新推荐文章于 2022-07-28 17:17:48 发布