排序


ABOUT SORT

#include<bits/stdc++.h>
using namespace std;
/*
	关于排序:
	1.冒泡排序 时间复杂度 O(n^2)
	2.选择排序 时间复杂度 O(n^2)
	3.直接插入排序 时间复杂度 O(n)~O(n^2) 空间复杂度O(1)
	4.希尔排序(在插入排序的基础上改进,跳着插) 时间复杂度O(n^1.5)
	5.堆排序 时间复杂度O(nlogn)
	6.桶排序 时间复杂度O(n) 空间占用较大
	7.基数排序 时间复杂度O(n*d) 空间复杂度O(n)
	8.归并排序 时间复杂度O(nlog2n)(分治策略)
	9.快速排序 时间复杂度O(nlogn){思想:二分}
	算法稳定性:
	稳定算法:1.2.3.4.
	时稳定的算法:6.7
	不稳定算法: 5.8.9
*/
//为堆排序准备的函数
/*
void heapfi(int *arr,int n,int i)
{
	if(i>=n)
		return ;
	int lchild = i*2+1; //左孩子下标
	int rchild = i*2+2; //右孩子下标
	int max = i ;//默认数值最大第节点为该叶子节点的值
	if(lchild <n && arr[lchild] > arr[max])//判断左孩子是否存在索引范围内及左孩子节点值是否大于根节点
		max=lchild;						   //大于的话就将较大值的下标记录在max里
	if(rchild <n && arr[rchild] > arr[max])//同上
		max=rchild;
	if(max!=i)
	{
		swap(arr[max],arr[i]); //如果最大值下标改变,则交换二者
		heapfi(arr,n,max);	   //对剩下部分不是完全二叉树继续进行堆的建立,递归
	}
}
void build_heap(int *arr)
{
	int n=20;
	int last_node = n-1;
	int parent=(last_node-1) / 2;//从后往前建堆
	for(int i = parent ;i>=0 ;i--)
	{
		heapfi(arr,n,i);
	}
}*/
//基数排序的函数
/*
int MaxBit(int *arr,int n)//求数组中最大数的位数
{
	int max=arr[0];
	for(int i=0;i<n;i++)
	{
		if(arr[i]>max)
			max=arr[i];
	}
	int sum=0;
	while(max>0)
	{
		max/=10;
		sum++;
	}
	return sum;
}
int GetNum(int num,int d)
{
	int p=1;
	while(d-1>0)
	{
		p*=10;
		d--;
	}
	return num/p%10;
}*/
//为归并排序准备的函数
/*
void merge(int *arr,int left,int mid,int right)
{
	int left_size=mid-left;
	int right_size=right-mid+1;
	int left_num[101];
	int right_num[101];
	int i,j,k;
	//将数组前半部分复制到left_num,right_num中
	for(i=left;i<mid;i++)
		left_num[i-left]=arr[i];
	for(i=mid;i<=right;i++)
		right_num[i-mid]=arr[i];
	i=j=0;
	k=left;
	//左右合并至一个数组中
	while(i<left_size && j<right_size)
	{
		if(left_num[i]<right_num[j])//按照从小到大依次放入arr中
		{
			arr[k]=left_num[i];
			i++;
			k++;
		}
		else
		{
			arr[k]=right_num[j];
			j++;
			k++;
		}
	}
	//放入剩余的
	while(i<left_size)
	{
		arr[k]=left_num[i];
		i++;
		k++;
	}
	while(j<right_size)
	{
		arr[k]=right_num[j];
		j++;
		k++;
	}
	return ;
}
void merge_sort(int *arr,int left,int right)
{
	if(left==right)
		return ;
	else
	{
		int mid=(left+right)/2;
		merge_sort(arr,left,mid);
		merge_sort(arr,mid+1,right);
		merge(arr,left,mid+1,right);
	}
	return ;
}*/
//快速排序的函数
/*
int part(int *arr,int left,int right)
{
	if(left>=right)
		return -1;
	int base=arr[left];//从最左边的元素为中心元素
	while(left<right)
	{
		while(left<right && arr[right] > base) //判断右侧元素是否大于中心元素,大于就继续遍历
			right--;
		if(left<right)							//否则就将右侧小于中心元素的元素挪到左边的位置
			swap(arr[left++],arr[right]);
			
		while(left<right && arr[left] <= base)//判断左侧元素是否小于中心元素,小于就继续遍历
			left++;				 
		if(left<right)
			swap(arr[left],arr[right--]);//否则就将左侧小于中心元素的元素挪到右边的位置
	}
	arr[left]=base;							//最后将中心放置左侧
	return left;	
}
void Quick_sort(int *arr,int left,int right)
{
	if(left<right)
	{
		int base=part(arr,left,right);
		Quick_sort(arr,left,base-1);//左边排序
		Quick_sort(arr,base+1,right);//右边排序
	}
	return ;
}*/
int main()
{
	default_random_engine e;//顺便学习一种生成大随机数的方法(为了装个×)
	std::ios::sync_with_stdio(false);
	cin.tie(0);
	int n=20;
	int arr[21];
	for(int i=0;i<n;i++)
		arr[i]=e()%100;
	cout<<"数组:";
	for(int i=0;i<n;i++)
		cout<<' '<<arr[i];
	cout<<endl;
//1.冒泡排序
//a.最原始的
/*
	for(int i=0;i<n-1;i++)
	{
		for(int j=i+1;j<n;j++)
		{
			if(arr[i]>arr[j])//大小修改在这里
				swap(arr[i],arr[j]);
		}
	}
*/
//b.常见的(优化后):
/*
	for(int i=0;i<n-1;i++)
	{
		for(int j=0;j<n-i-1;j++)
		{
			if(arr[j]>arr[j+1])//大小修改在这里
			{
				swap(arr[j],arr[j+1]);
			}
		}
	}
*/
//c.最佳的冒泡排序 但空间复杂度O(1)
/* 
	bool flag=true;
	for(int i=0;i<n-1 && flag;i++)
	{
		flag=false;
		for(int j=0;j<n-i-1;j++)
		{
			if(arr[j]>arr[j+1])//大小修改在这里
			{
				swap(arr[j],arr[j+1]);
				flag=true;
			}
			
		}
	}
	//用flag成功优化了冒泡
*/	
//2.选择排序(性能略优与冒泡排序)
/*
	int minn;
	for(int i=0;i<n;i++)
	{
		minn=i;
		for(int j=i+1;j<n;j++)
		{
			if(arr[j]<arr[minn])
				minn=j;
		}
		swap(arr[minn],arr[i]);
	}
*/
//3.直接插入排序
/*
	for(int i=1;i<n;i++)//从索引1开始 往前插入
	{
		int temp=arr[i];
		int j=i-1;
		for(j;j>=0 && arr[j]>temp;j--)//前面的数 > 后面的数,实现后移
			arr[j+1]=arr[j];
		arr[j+1]=temp;
	}
*/
//4.希尔排序
/*
	int gap=n; //增量
	while(gap>1)
	{
		gap = gap/3+1;
		for(int i=gap;i<n;i++)
		{
			int temp=arr[i];
			int j=i-gap;
			for(j;j>=0 && arr[j]>temp ;j= j-gap)//跳跃式前移
			{
				arr[j+gap]=arr[j];
			}
			arr[j+gap]=temp;
		}
	}
*/
//5. 堆排序
/*
	build_heap(arr); //先建立一个大根堆
	for(int i=n-1;i>=0;i--)
	{
		swap(arr[i],arr[0]);
		heapfi(arr,i,0);
	}
*/
//6.桶排序(有相当的局限性,会自动去重用,set或multiset(不去重)做更好,这里不演示)
//因为数据大小,桶排序没有固定写法。
//7.基数排序(非负数)
/*
	int bucket[21];//创建临时存放排序过程数据的数组
	int count[15];//创建按位计数的计数容器,即记录个位、十位、百位……各个数的位置的个数
	
	for(int d=1;d<=MaxBit(arr,n);d++)
	{
		memset(count,0,sizeof(count));//初始化
		
		//统计各个桶中的个数
		for(int i=0;i<n;i++)
			count[GetNum(arr[i],d)]++;
		//得到某个数应该放入bucket的位置
		for(int i=1;i<15;i++)
		{
			count[i]+=count[i-1];
		}
		for(int i=n-1;i>=0;i--)
		{
			int k=GetNum(arr[i],d);
			bucket[count[k]-1]=arr[i];
			count[k]--;
		}
		for(int j=0;j<n;j++)
		{
			arr[j]=bucket[j];
		}
	}
*/	
//8.归并排序(自己看函数吧)
/*
	//merge(arr,0,n/2,n);
	merge_sort(arr,0,n);
*/
//9.快速排序
//	Quick_sort(arr,0,n);
	
	
//最后让大家感受一下STL的强大
/*
经过优化的快速排序算法:
sort(begin,end)
sort(begin,end,op)

使用归并排序算法:
stable_sort(begin,end)
stable_sort(begin,end,op)

使用堆排序算法:(局部排序)
partial_sort(begin,sortEnd,end)
partial_sort(begin,sortEnd,end,op)

根据第n个位置排序(快速排序算法):
nth_element(beg,nth,end)
nth_element(beg,nth,end,op)

*/	
//最后表演一个最常用的sort
	sort(arr,arr+n);
	cout<<"排序后:";
	for(int i=0;i<n;i++)
		cout<<' '<<arr[i];
	cout<<endl;	//完结撒花!
	return 0;
}
posted @ 2026-02-23 08:59  唐极Coder  阅读(0)  评论(0)    收藏  举报