排序算法:稳定性,时间复杂度,空间复杂度

排序是十分常用的算法,所以来一起看以下几种排序:

稳定性的定义:若两个数相等,那么排序之后,两个数字的相对位置保持不变

时间复杂度:对排序数据的操作次数

空间复杂度:算法在执行时所需要存储空间的大小

  • 冒泡排序的基本思想:依次比较,相邻是逆序的就交换,经过多次比较,最终得到有序的序列,如下图                                                                     

以下是冒泡排序的代码:时间复杂度 1.最坏O(n^2)  2.平均O(n^2)         空间复杂度O(1)       稳定

 

  • 选择排序:先将最小的数据放在头部,再找出剩下数据中最小的放入有序的数据中,直到有序                                                                           

代码:时间复杂度:1.最坏O(N^2)  2.平均O(N^2)    空间复杂度:O(1)      不稳定

 

  • 插入排序:构建有序的序列,再将无序的插入合适的位置,如下图     

                                

代码:时间复杂度:1.最坏O(N^2)  2.平均O(N^2)    空间复杂度:O(1)         稳定

void insertsort(vector<int>& array,int n)
{
     int j = 0,i = 0;
     for(i = 1;i < n;i++)
     {
         int temp = array[i];//记录当前元素
         for( j = i-1 ; j >= 0 ; j--)
         {
             if(temp < array[j])
             {
                 array[j+1] = array[j];//向后搬移
             }else{
                  break;
             }
         }
         array[j+1] = temp; //把当前元素放到最终位置
      }
}

 

  • 快排:找一个基准值,左侧比他小,右侧比他大,再对子序列排序,达到整个序列有序

                             

代码:时间复杂度:1.最坏:O(n^2)      2.平均:O(nlgn)                  空间复杂度:O(n^2)           不稳定

	int Search(std::vector<int>& arr, int left, int right)//左右指针交换法
	{
		int head = left;
		int tail = right - 1;
		int key = arr[right];
		while (head<tail)
		{
			while (head < tail&&arr[head] < key)
				head++;
			while (head<tail&&arr[tail]>key)
				tail--;
			std::swap(arr[head], arr[tail]);
		}
		if (arr[tail]>key)
			std::swap(arr[tail], arr[right]);//将key值的位置放到正确的位置
		return tail;
	}
	void QuickSort(std::vector<int>& arr, int left, int right)
	{
		if (left >= right)
			return;
		int point = Search(arr, left, right);
		QuickSort(arr, left, point-1);
		QuickSort(arr, point+1, right);
	}
  • 希尔排序:将序列分为多个子序列进行分别进行直接插入排序。定义一个间隔序列,每次以相同的间隔数分为一组,进行插入排序。希尔排序的实质就是分组的插入排序。
  • 归并排序:将已经排好序的两个序列和并为一个有序的序列,如图

                                                   这里写图片描述

时间复杂度:O(nlgn)             空间复杂度:O(n)             稳定

void Guibing(vector<int>& v, int head, int mid, int tail)
//对已排好的两个数组进行合并
{
	int *arr = new int[tail - head + 1];//辅助空间
	int i = head, j = mid + 1;
	int tmp = 0;
	while (i <= mid&&j <= tail)
	{
		if (v[i] <= v[j])
			arr[tmp++] = v[i++];
		if (v[i] > v[j])
			arr[tmp++] = v[j++];
	}
	while (i <= mid)
	{
		arr[tmp++] = v[i++];
	}
	while (j <= tail)//将一组剩余的放进去
	{
		arr[tmp++] = v[j++];
	}
	for (int a = 0, b = head; a<tmp&&b<=tail;)//放到原数组中
	{
		v[b++] = arr[a++];
	}
	delete[] arr;
	
}
void Sort(vector<int>& v, int head, int tail)
//归并,先分,再排,分治思想分而治之,将长数组一直进行二等分,当分到只剩一个时返回
{
	if (head >= tail)
		return;
	int mid = (tail - head) / 2 + head;
	Sort(v, head, mid);
	Sort(v, mid + 1, tail);
	Guibing(v, head, mid, tail);
}
int main()
{
	vector<int> v = { 9, 1, 8, 2, 7, 3, 6, 4, 5 };
	int left = 0;
	int right = v.size() - 1;
	Sort(v, left, right);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值