数据结构-内排序

1. 直接插入排序
void insertSort(int q[],int n){
    int i, j, temp;
	for (i = 2; i <= n; i++) {
        //当有序区间的最后一个元素大于当前元素时
		if (q[i-1] > q[i]) {						
			temp = q[i];
			for (j = i-1; j >= 0 && q[j] > temp; j--){//升序排序
				q[j+1] = q[j];	
			}
			q[j+1] = temp;
		}
	}    
}

控件复杂度:O(1)

时间复杂度:O(n2)

​ 最好情况:数组已有序,此时没插入一个元素,只需要比较而不用移动元素,为O(n)

​ 最坏情况:数组为逆序,比较次数最大为 ∑ i = 2 n i \sum_{i=2}^{n} i i=2ni = n ( n − 1 ) n \frac{n(n - 1)}{n} nn(n1) = O(n2),移动次数最大为 ∑ i = 2 n ( i + 1 ) \sum_{i=2}^{n} (i + 1) i=2n(i+1) = ( n − 1 ) ( n + 4 ) 2 \frac{(n - 1)(n + 4)}{2} 2(n1)(n+4) = O(n2)

是否稳定:是

2. 折半插入排序
void binInserSort(int q[],int n){
	int i, j, temp;
	for (i = 2; i <= n; i++) {
		if (q[i-1] > q[i]) {
			temp = q[i];
            //二分查找有序区间[0,i-1]
			int l = 0, r = i - 1;
			while (l <= r) {
				int mid = l + r >> 1;
				if (q[mid] > temp) r = mid - 1;			//在左半区
				else l = mid + 1;						//在右半区
			}
			for (j = i - 1; j >= r + 1; j--) {
				q[j+1] = q[j];
			}
			q[j+1] = temp;
		}
	}
}

空间复杂度:O(1)

时间复杂度:O(n2)

​ 仅减少了比较元素的次数,约为O(nlog2n),移动次数未改变

是否稳定:是

3. 希尔排序
void shellSort(int q[],int n) {				//希尔排序
	int i, j, d, temp;
	//进行分组,最开始的增量d为数组长度的一半
	for (d = n/2; d > 0; d /= 2) {
		//对各个分组进行插入排序
		for (i = d; i <= n; i++) {
			temp = q[i];
			//插入的时候按组进行插入(组内的相邻元素物理地址上相隔d)
			for (j = i - d; j >= 0 && q[j] > temp; j -= d) {
				q[j + d] = q[j];
			}
			q[j + d] = temp;
		}
	}
}

空间复杂度:O(1)

时间复杂度:O(n1.3)

​ 希尔排序时间复杂度难以分析,一般约为O(n1.3);最坏为O(n2)

是否稳定:否

4. 冒泡排序
void bubbleSort(int q[],int n) {			//冒泡排序
    for (int i = 1; i < n; i++) {
        bool flag = false;
		for (int j = n; j > i; j--) {
			if (q[j-1] > q[j]) {			//若为逆序
				swap(q[j-1], q[j]);
                flag = true;
			}
		}
        if(!flag) return;		//本次没有发生交换,中途结束算法
	}
}

空间复杂度:O(1)

时间复杂度:O(n2)

​ 最好情况:数组已有序,比较次数为O(n),移动次数为0

​ 最坏情况:数组为逆序,比较次数最大为 ∑ i = 1 n − 1 ( n − i ) \sum_{i=1}^{n-1} (n-i) i=1n1(ni) = n ( n − 1 ) 2 \frac{n(n - 1)}{2} 2n(n1) = O(n2),移动次数最大为 ∑ i = 1 n − 1 3 ( n − i ) \sum_{i=1}^{n-1} 3(n - i) i=1n13(ni) = 3 n ( n − 1 ) 2 \frac{3n(n - 1)}{2} 23n(n1) = O(n2)

是否稳定:是

5. 快速排序
void quickSort(int q[],int l,int r) {	
    if(l >= r) return;
    int i = l-1, j = r+1,x = q[l+r >> 1];
    while (i < j) {
        while (q[++i] < x);
        while (q[--j] > x);
        if (i < j) swap(q[i], q[j]);
    }
    swap( q[l], q[j]);
    quickSort(q,l, j);
    quickSort(q,j + 1, r);
}

空间复杂度:O(log2n)

​ 最好情况:每次都将n个元素划分为两次长度差不多相同的子区间,为O(log2n)

​ 最坏情况:划分的两个区间分别包含0个和n-1个元素,为O(n)

时间复杂度:O(n2)

​ 最好情况:每次都将n个元素划分为两次长度差不多相同的子区间,为O(nlog2n)

​ 最坏情况:划分的两个区间分别包含0个和n-1个元素,为O(n2)

是否稳定:否

6. 简单选择排序
void seleSort(int q[],int n) {				
	int i, j, temp, min;
	for (i = 1; i < n; i++) {
		min = i;					//记录最小元素下标
        //从q[i,n-1]中选择最小元素,因为q[0,i]已排好序
		for (j = i+1; j <= n; j++) {	
			if (q[min] > q[j])
				min = j;
		}
        if(min != i) swap(q[i], q[min]);
	}
}

空间复杂度:O(1)

时间复杂度:O(n2)

​ 最好情况:数组已有序,比较次数无论好坏均为 n ( n − 1 ) 2 \frac{n(n - 1)}{2} 2n(n1),移动次数为0

​ 最坏情况:数组为逆序,移动次数为3(n-1)

是否稳定:否

7. 堆排序
void down(int u,int size)					//堆的区间长度[1...size]
{
    int temp = q[u];						//将q[i]存为子树的根节点
    for(int j = u*2;j <= size ;j *= 2)	
    {
        //如果u有右孩子,并且右孩子值比左孩子大,则将j指向右孩子
        if(j+1 <= size && q[j] < q[j+1]) j++;	
        //如果u的孩子的最大值比自身大,则将j与u的位置交换
        if(q[j] > temp)		
        {
            q[u] = q[j];
            u = j;
        }
        else break;
    }
    q[u] = temp;	//将q[u]的值放置在合适位置
}
//构造大根堆
void heapSort(int q,int n){
    for(int i = n/2;i > 0;i--) down(i,n);
    swap(q[1],q[n]);  //此时q[1]为堆区间最大值,将其移到最后
    
    for(int i = n-1;i > 0;i--){ //执行n-1次操作
        down(1,i);
  		swap(q[1],q[i]);
    }
}

空间复杂度:O(1)

时间复杂度:O(nlog2n)

是否稳定:否

8. 归并排序
int t[N];
void merging(int q[],int low,int mid,int high) {		//归并操作
	int k = low;
    int l,r;
	for (l = low, r = mid + 1; l <= mid && r <= high; ) {
		if (q[l] <= q[r]) t[k++] = q[l++];
		else t[k++] = q[r++];
	}
	while (l <= mid)  t[k++] = q[l++]; 
	while (r <= high) t[k++] = q[r++]; 
	for (l = low; l <= high; l++) q[l] = t[l];
}
void mergeSort(int q[],int low ,int high) {	
	if (low >= high) return; 
	int mid = (low + high) / 2;		//从中间划分区间
	mergeSort(q,low, mid);			//排列左区间
	mergeSort(q,mid + 1, high);		//排列右区间
	merging(q,low, mid, high);		//归并左右区间

}

空间复杂度:O(n),辅助数组大小最大为n

时间复杂度:O(nlog2n)

​ 每次归并时间为O(n),共需要进行log2n趟归并

是否稳定: 是

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值