常用的排序算法的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--;
		}
		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[]={2,6,3,1,4,5,1,21,12,3};
	Display(a,sizeof(a)/sizeof(int));//显示排序前的元素
	//void (*pSort)(int*,int)=NULL;//定义一个函数指针,方法一
	typedef void (*Fun)(int *,int);//Fun为函数指针类
	Fun pSort=NULL;//定义函数指针,方法二,与上面等价
//	pSort=InsertSort;
//	pSort=BubbleSort;
//	pSort=SelectSort;
//	pSort=QuickSort;
//	pSort=ShellSort;
	pSort=HeapSort;
	if(pSort)
	{
		pSort(a,sizeof(a)/sizeof(int));//显示排序后的元素
	}
	Display(a,sizeof(a)/sizeof(int));
	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值