常见的排序算法:冒泡排序、直接插入、希尔排序,堆排序,简单选择排序,快速排序。这些最基本的算法都是应该熟练掌握的,下面是C++实现的代码,方便大家学习参考:
#include<iostream>
using namespace std;
void swap(int &i,int &j)//实现i,j交换的函数
{
i=i^j;
j=i^j;
i=i^j;
}
void Display(const int *arr,int length)
{
if(arr==NULL || length<=0)
{
return ;
}
int i;
for(i=0;i<length;i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
/*****************直接插入排序***********************/
void InsertSort(int *arr,int length)//直接插入排序
{
if(arr==NULL || length<=1)//如果大小为1也无需再排序
{
return ;
}
int i;
for(i=1;i<length;i++)//从第二个值开始插
{
int temp=arr[i];//先保存待插入的值,因为移动会被覆盖
int j;
for(j=i-1;j>=0 && arr[j]>temp;j--)//一边比较一边移动
{
arr[j+1]=arr[j];
}
if(i!=j+1)//如果前面存在比a[i]小的数
{
arr[j+1]=temp;//在当前值的下一个位置插入
}
}
}
/*************************冒泡排序**************************/
void BubbleSort(int *arr,int length)//冒泡排序
{
if(arr==NULL || length<=1)
{
return ;
}
int i,j;
bool change=true;//对冒泡排序的优化
for(i=0;i<length-1 && change;i++)//i表示最多冒泡的次数
{
change=false;
for(j=0;j<length-1-i;j++)
{
if(arr[j]>arr[j+1])//通过异或实现高效数据交换
{
swap(arr[j],arr[j+1]);
change=true;
}
}
}
}
/******************简单选择排序************************/
void SelectSort(int *arr,int length)//简单选择排序
{
if(arr==NULL || length<=1)
{
return ;
}
int i,min;
for(i=0;i<length-1;i++)
{
min=i;//每次假设第一个值为最小值
int j;
for(j=i+1;j<length;j++)
{
if(arr[min]>arr[j])
{
min=j;//记下当前最小值的位置
}
}
if(min!=i)
{
swap(arr[i],arr[min]);
}
}
}
快速排序
int Partition(int *arr,int left,int right)//将数组一分为二,并寻找支点的位置
{
int x=arr[left];//每次将第一个值作为支点的值
while(left<right)
{
while(arr[right]>=x && left<right)//从右向左扫描,注意是小于等于
{
right--;
}
if(left<right)
{
swap(arr[left],arr[right]);
}
while(arr[left]<=x && left<right)//从左向右扫描,注意是小于等于
{
left++;
}
if(left<right)
{
swap(arr[left],arr[right]);
}
}
return left;//此时left等于right
}
void QSort(int *arr,int left,int right)//快速排序,left=0,right=length-1
{
if(left<right)
{
int mid=Partition(arr,left,right);
QSort(arr,left,mid-1);
QSort(arr,mid+1,right);
}
}
void QuickSort(int *arr,int length)
{
if(arr==NULL || length<=1)
{
return ;
}
QSort(arr,0,length-1);
}
//归并排序/
void Merge(int *arr,int first,int mid,int last,int *temp)//将arr[first...mid]与arr[mid+1...last]归并
{
int i,j;
int k=0;
for(i=first,j=mid+1;i<=mid && j<=last;)
{
if(arr[i]<=arr[j])//所以是稳定排序
{
temp[k++]=arr[i++];
}
else
{
temp[k++]=arr[j++];
}
}
while(i<=mid)
{
temp[k++]=arr[i++];
}
while(j<=last)
{
temp[k++]=arr[j++];
}
for(i=0;i<k;i++)//将合并后的数组temp[]还原到arr[]
{
arr[first+i]=temp[i];//是arr[low+i]不是arr[i]
}
}
void Msort(int *arr,int first,int last,int *temp)
{
if(first==last)
{
temp[first]=arr[first];
}
else if(first<last)
{
int mid=(first+last)/2;
Msort(arr,first,mid,temp);
Msort(arr,mid+1,last,temp);
Merge(arr,first,mid,last,temp);
}
}
void MergeSort(int *arr,int length)//归并排序
{
if(arr==NULL || length<=1)
{
return ;
}
int *temp=new int [length];
Msort(arr,0,length-1,temp);
delete []temp;
}
//希尔排序
void ShellInsert(int *arr,int length,int d)
{
int i,j;
for(i=d;i<length;i++)
{
int temp=arr[i];
for(j=i-d;j>=0 && arr[j]>temp;j-=d)
{
arr[j+d]=arr[j];
}
if(j!=i-d)
{
arr[j+d]=temp;
}
}
}
void ShellSort(int *arr,int length)//希尔排序
{
if(arr==NULL || length<=1)
{
return ;
}
int d=length/2;
while(d>=1)
{
ShellInsert(arr,length,d);
d/=2;
}
}
堆排序(大顶堆)//
///堆是一个完全二叉树,若结点索引从0开始,则i结点的左孩子为2*i+1,右为2*i+2
void HeapAdjustDown(int *arr,int length,int i)//对第i个值做向下调整,i=0,...,length-1
{
if(arr==NULL || length<=0 || i<0)
{
return ;
}
int temp=arr[i];
int j;//i相当于前驱,j相当于后继
for(j=2*i+1;j<length;)//即j<=length-1
{
if(j+1<length && arr[j]<arr[j+1])//如果存在右孩子,且右孩子值待遇
{
j++;//与右孩子交换
}
if(arr[j]<=temp)//如果左右孩子中的较大值小于该结点值,则说明无需向下调整了
{
break;
}
else//如果左右孩子中的较大值大于该结点值,则想到直接插入排序
{
arr[i]=arr[j];//孩子结点值中较大的上移动
i=j;//i用于追踪待插入点的位置
j=2*i+1;
}
}
if(arr[i]!=temp)//如果i的值发生了移动
{
arr[i]=temp;//将最初第i个节点值放入合适的位置
}
}
void CreateHeap(int *arr,int length)//创建一个堆
{
if(arr==NULL || length<=0)
{
return ;
}
int i;
for(i=(length-2)/2;i>=0;i--)//最后一个元素的序号为length-1,故该结点的父结点为(length-2)/2
{
HeapAdjustDown(arr,length,i);//从倒数第二行开始倒着向下调整
}
}
void HeapDelete(int *arr,int len)//删堆顶元素,len表示当前表的长度
{
if(arr==NULL || len<=0 || len==1)//len=1,表示当堆中只有一个元素时,无需排序
{
return ;
}
else
{
swap(arr[0],arr[len-1]);
HeapAdjustDown(arr,len-1,0);//删除后,数组长度减1了
}
}
void HeapSort(int *arr,int length)//堆排序
{
if(arr==NULL || length<=1)
{
return ;
}
CreateHeap(arr,length);//先创建一个堆0
int i;
for(i=0;i<=length-1;i++)//删除length-1次即可,因为最后一个元素就剩自己了
{
HeapDelete(arr,length-i);
}
}
int main()
{
int a[]={12,3,5,1,4,5,4,21,1,3};
Display(a,sizeof(a)/sizeof(int));//显示排序前的元素
//void (*pSort)(int*,int)=NULL;//定义一个函数指针,方法一
typedef void (*Fun)(int *,int);//Fun为函数指针类
Fun pFunc=NULL;//定义函数指针,方法二,与上面等价
pFunc=InsertSort;
// pFunc=BubbleSort;
// pFunc=SelectSort;
// <span style="font-family: Arial, Helvetica, sans-serif;">pFunc</span><span style="font-family: Arial, Helvetica, sans-serif;">=QuickSort;</span>
// <span style="font-family: Arial, Helvetica, sans-serif;">pFunc</span><span style="font-family: Arial, Helvetica, sans-serif;">=ShellSort;</span>
// pFunc=HeapSort;
if(pSort)
{
pSort(a,sizeof(a)/sizeof(int));//显示排序后的元素
}
Display(a,sizeof(a)/sizeof(int));
system("pause");
return 0;
}