各种排序时间空间复杂度与稳定性,以及相关代码的实现(C++)

名称分类时间复杂度空间复杂度稳定性
直接插入排序插入类

最好 O(n)

最坏O(n^2)

平均O(n^2)

O(1)稳定
折半插入排序

最好 O(n)

最坏O(n^2)

平均O(n^2)

O(1)稳定
希尔排序

最好O(n^1.3)

最坏O(n^2)

平均O(nlogn)

O(1)不稳定
冒泡排序交换类

最好 O(n)

最坏O(n^2)

平均O(n^2)

O(1)稳定
快速排序

最好O(nlogn)

最坏O(n^2)

平均O(nlogn)

最好O(nlogn)

最坏O(n)

平均O(nlogn)

(产生于递归的深度)

不稳定
简单选择排序选择类O(n^2)O(1)不稳定
堆排序O(nlogn)O(1)不稳定
归并排序O(nlogn)O(n)稳定
基数排序桶思想类

O(d(n+k))

d:分配和收集的趟数

n:每趟待排序数目

k:需要的辅助队列数目

O(n+k)稳定

插入类:

void insertsort(int *arr,int length)
{
	if(length<=1)
	{
		cout<<"数组长度为1,无需排序"<<endl;
	}
	for(int i=1;i<length;i++)
	{
		if(arr[i]<arr[i-1])
		{
			int temp = arr[i];
		    int j;
		    for(j=i-1;j>=0&&arr[j]>temp;j--)
		    {
			  arr[j+1] = arr[j];
		    }
		    arr[j+1] = temp;
		}
	}
	cout<<"直接排序的结果为:"<<endl;
	for(int i=0;i<length;i++)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
//二分插入排序
void halfinsertsort(int *arr,int length)
{
	if(length<=1)
	{
		cout<<"数组长度为1,无需排序"<<endl;
	}
	for(int i =1;i<length;i++)
	{
		if(arr[i]<arr[i-1])
		{
			int temp = arr[i];
		int left = 0;
		int right = i-1;
		while(left<=right)//查找插入位置
		{
			int mid = (right-left)/2+left;
			if(arr[mid]>temp)
			{
				right = mid-1;
			}
			else
			{
				left = mid+1;
			}
		}
		for(int j =i-1;j>=right+1;j--)
		{
			arr[j+1]=arr[j];
		}
		arr[right+1] = temp;
	}
}
	cout<<"二分排序为:"<<endl;
	for(int i=0;i<length;i++)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
//希尔排序
void xiersort(int *arr,int length)
{
	if(length<=1)
	{
		cout<<"数组长度为1,无需排序"<<endl;
	}
	cout<<"原始数组为:"<<endl;
	for(int i=0;i<length;i++)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
	int dim = length/2;//设置增量
	while(dim>=1)
	{
		for(int i=dim;i<length;i++)
		{
			if(arr[i]<arr[i-dim])
			{
               int temp = arr[i];
               int j;
               for(j = i-dim;j>=0&&arr[j]>temp;j = j-dim)
               {
                  arr[j+dim] = arr[j];
               }
               arr[j+dim] = temp;
			}
		}
		cout<<"本次排序,增量为:"<<dim<<endl;
		for(int i =0;i<length;i++)
		{
			cout<<arr[i]<<" ";
		}
		cout<<endl;
		dim = dim/2;
	}
}

交换类

//冒泡排序
void maopaosort(int *arr,int length)
{
	if(length<=1)
	{
		cout<<"数组长度为1,不需要排序"<<endl;
	}
	bool type = false;
	for(int i=0;i<length-1;i++)
	{
		for(int j=0;j<length-1-i;j++)
		{
			if(arr[j]>arr[j+1])
			{
				int temp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = temp;
				type = true;
			}
		}
		if(type == false)
			break;
	}
	for(int i=0;i<length;i++)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
//快速排序
int partition(int *arr,int low,int high)//都不是传的引用,并不会影响实际的值
{
   int temp = arr[low];
   while(low<high)
   {
   	while(low<high&&arr[high]>=temp)
   		high--;
    if(low==high)
    	break;
    if(low<high)
        arr[low] = arr[high];
    while(low<high&&arr[low]<=temp)
    	low++;
    if(low==high)
    	break;
    if(low<high)
        arr[high] = arr[low];
   }
   arr[low] = temp;
   return low;
}
void choosesort(int *arr,int low,int high,int length)
{
   assert(low<high);
   int temp = partition(arr,low,high);
   cout<<"本轮排序的low:"<<low<<" high:"<<high<<" 轴为:"<<temp<<endl;
   for(int i =0;i<length;i++)
   {
      cout<<arr[i]<<" ";
   }
   cout<<endl;
   if((temp-1)>low)
   	choosesort(arr,low,temp-1,length);
   if((temp+1)<high)
   	choosesort(arr,temp+1,high,length);
}
void choosesort(int* arr,int length)
{
	if(length<=1)
	{
		cout<<"数组长度为1,不需要排序"<<endl;
	}
	int low = 0;
	int high = length - 1;
	choosesort(arr,low,high,length);
}

选择类

//简单选择排序
void simsort(int *arr,int length)
{
	if(length<=1)
	{
		cout<<"数组长度为1,无需排序"<<endl;
	}
	for(int i =0;i<length-1;i++)
	{
		int minidx = i;
		for(int j=i+1;j<length;j++)
		{
			if(arr[j]<arr[minidx])
			{
				minidx = j;
 			}
		}
 			if(minidx != i)
 			{
 				int temp = arr[minidx];
 				arr[minidx] = arr[i];
 				arr[i] = temp;
 			}
	}
	for(int i=0;i<length;i++)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}
void adjustdown(int* arr,int length,int cur)
{
	int i = cur;
	int j = cur*2+1;
	while(j<length)
	{
		if(j+1<length)//有右孩子
		{
			if(arr[j+1]>arr[j])
			{
				j=j+1;
			}
		}
		if(arr[i]>arr[j])
		{
			break;
		}
		int temp = arr[j];
		arr[j] = arr[i];
		arr[i] = temp;
		i=j;
		j = j*2+1;
	}
}
void removemaxvalue(int*arr,int length)
{
	if(length-1==0)
		return;
	int temp = arr[0];
	arr[0] = arr[length-1];
	arr[length-1] = temp;
	adjustdown(arr,length-1,0);
}
//堆排序
void stacksort(int *arr,int length)
{
	if(length<=1)
	{
		cout<<"数组长度为1,不需要排序"<<endl;
	}
	int cur = length/2-1;//找到第一个非叶子节点
	while(cur>=0)
	{
		adjustdown(arr,length,cur);//调整该节点的子树
		cur--;
	}//构造大栈顶
	for(int i=0;i<length-1;i++)
	{
		removemaxvalue(arr,length-i);//换根,重新调回大栈顶
	}
	for(int i=0;i<length;i++)
	{
		cout<<arr[i]<<" ";
	}
	cout<<endl;
}

归并排序

//递归方式
void merge(int *arr,int* temp,int left,int mid, int right,int length)
{
	for(int i=left;i<=right;i++)
	{
		temp[i] = arr[i];
	}
	int cur1 = left;//左序列第一个
	int cur2 = mid+1;//右序列第一个
	int cur3 = left;//新序列的第一个
	while(cur1<=mid&&cur2<=right)
	{
		if(temp[cur1]<=temp[cur2])
		{
			arr[cur3] = temp[cur1];
			cur1++;
		}
		else
		{
			arr[cur3] = temp[cur2];
			cur2++;
		}
		cur3++;
	}
		while(cur1<=mid)
		{
			arr[cur3] = temp[cur1];
		    cur1++;
		    cur3++;
		}
		while(cur2<=right)
		{
			arr[cur3] = temp[cur2];
		    cur2++;
		    cur3++;
		}
}
void mergesort(int* arr,int*temp,int left,int right,int length)//划分数组
{
  int mid = (right+left)/2;
  if(left>=right)
  	return;
  mergesort(arr,temp,left,mid,length);
  mergesort(arr,temp,mid+1,right,length);
  merge(arr,temp,left,mid,right,length);//将左右两边合到一起
}
void mergesort(int *arr,int length)
{
	if(length<=1)
	{
		cout<<"数组长度为1,无需排序"<<endl;
	}
	int* temparray = new int[length];
	mergesort(arr,temparray,0,length-1,length); //length仅仅作为显示使用 
	delete []temparray;
}
//非递归排序
void mergesort_nodigui(int*arr,int length)
{
	if(length<=1)
	{
		cout<<"数组长度为1,无需排序"<<endl;
	}
	int step = 1;//子序列间的间隔
	int subsetoatl = length;//当前子序列的数目
	int left,right,mid;
	int* temp = new int[length];
	while(subsetoatl>1)
	{
		for(int i=0;i<length;i=i+step*2)//遍历每个子列
		{
			left = i;
			mid = left+step-1;
			if(mid>=length)
			{
				break;
			}
			right = mid+(mid-left+1);
			if(right>=length)
			{
				right = length-1;
			}
			if(left<=mid&&left<right&&mid<right)
			{
				merge(arr,temp,left,mid,right,length);
				subsetoatl--;
			}
			else
			{
				break;
			}
		}
		step*=2;
	}
	delete []temp;
}

基数排序

void radixsort(int*arr,int length)
{
	if(length<=1)
	{
		cout<<"数组长度为1,无需排序"<<endl;
	}
	int* temp = new int[length];
	list<int *>mylist[10];//0~9
	//分配
	for(int i=0;i<3;i++)
	{
		for(int j=0;j<length;j++)
		{
			int tmpi=i;//判断比较哪一位
			int value = arr[j];
			int lastvalue;//存放个位十位百位
			while(tmpi>=0)
			{
				lastvalue = value%10;
				value = value/10;
				tmpi--;
			}
			mylist[lastvalue].push_back(&arr[j]);//余数对应下标
		}
	//收集
		int idx = 0;
		for(int k=0;k<10;k++)//就0-9十个位置
		{
			for(auto iter = mylist[k].begin();iter!=mylist[k].end();iter++)
			{
				temp[idx] = *(*(iter));
				idx++;
			}
			mylist[k].clear();
		}
	    cout<<"第"<<i<<"次排序结果"<<endl;
		for(int m = 0;m<length;m++)
		{
            cout<<temp[m]<<" ";
		}
		cout<<endl;
		for(int m=0;m<length;m++)
        {
	        arr[m] = temp[m];
        }//下一次分配要建立在上一次的收集成果之上
 
	}
    delete []temp;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值