排序

本文详细介绍了几种常见的排序算法,包括冒泡排序、快速排序、归并排序、插入排序和堆排序等。通过源代码展示了每种算法的具体实现方式,并分析了它们的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <set>
#include <queue>
#include <string.h>
#define INF 0x3fffffff
#define maxn 10005

typedef long long LL;

using namespace std;

int aa[maxn];

/*
冒泡排序,比较相邻二个数的值,将最大的移到右边。
依次比较相邻的两个数,将比较小的数放在前面,比较大的数放在后面。
这样每次循环将最大值移到最右边,循环一下,这个数字就是有序的。

N个数字要排序完成,总共进行N-1趟排序,每i趟的排序次数为(N-i)次,所以可以用双重循环语句,外层控制循环多少趟,内层控制每一趟的循环次数
*/

/*
T(n) = a*T(n/b)+f(n)
如果a=b=2时,即每次划分都是按照折半划分,那么其时间复杂度是0(nlogn),
但是我们考虑另外一种极端的情况,就是每次划分都是
T(n) = T(n-1)+T(1)+f(n),这就是我们平时说的有序的情况,
如1,2,3,4,5,那么每次第一次划分的地方就是1,这样其实就退化成0(n2).
*/
void quick_sort(int *a, int left, int right) {
    if (left < right) {
        int temp = a[left];
        int low = left;
        int high = right;
        while (low < high) {
            while (low < high && a[high] > temp) {
                high--;
            }
            a[low] = a[high];
            while (low < high && a[low] < temp) {
                low++;
            }
            a[high] = a[low];
        }
        a[low] = temp;
        quick_sort(a, left, low-1);
        quick_sort(a, low+1, right);
    }
}
// int Infinite : INT_MAX
// nlogn, 但是拷贝数组开销大
void merge(int A[], int p, int q, int r)
{
	// two part
	// A[p...q], A[q+1...r]
	int n1 = q - p + 1;
	int n2 = r - (q+1) + 1;
	// new array
	int L[n1+2];
	int R[n2+2];
	// set value
	for (int i = 1; i <= n1; i++)
	{
		L[i] = A[p+i-1];
	}
	for (int i = 1; i <= n2; i++)
	{
		R[i] = A[q+i];
	}
	// set the bottom num to the max
	L[n1+1] = INT_MAX;
	R[n2+1] = INT_MAX;
	// define i, j
	int i = 1;
	int j = 1;
	for (int k = p; k <= r; k++)
	{
		if (L[i] <= R[j])
		{
			A[k] = L[i];
			i++;
		}
		else
		{
			A[k] = R[j];
			j++;
		}
	}
}
void merge_sort(int A[], int p, int r)
{
	if (p < r)
	{
		int q = (p+r)/2;
		merge_sort(A, p, q);
		merge_sort(A, q+1, r);
		merge(A, p, q, r);
	}
}

/*
对于少量元素的排序,它是一个有效的算法.
它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动
* 最优情况,都是有序的O(n),
* 最坏情况,O(n^2)
*/
void insert_sort(int A[], int n)
{
	int i;
	for (int j = 2; j <= n; j++)
	{
		A[0] = A[j];
		i = j - 1;
		while (i >0 && A[i] > A[0])
		{
			A[i+1] = A[i];
			i--;
		}
		A[i+1] = A[0];
	}
}
/*
a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;
b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
*/
int heap[maxn];
int num = 0;
void push(int x) {
    int i = num;
    num++;
    while (i > 0) {
        int p = (i-1)  / 2;
        if (heap[p] <= x) break;
        heap[i] = heap[p];
        i = p;
    }
    heap[i] = x;
}

int pop() {
    int ret = heap[0];
    num--;
    int x = heap[num];
    int i = 0;
    while (i*2+1 < num) {
        int a = i*2 + 1;
        int b = i*2 + 2;
        // 比较二个儿子
        if (b < num && heap[b] < heap[a]) a = b;
        if (heap[a] >= x) break;
        heap[i] = heap[a];
        i = a;
    }
    heap[i] = x;
    return ret;
}

void heap_sort(int *a, int n) {
    num = 0;
    for (int i = 0; i < n; i++) {
        push(a[i]);
    }
    for (int i = 0; i < n; i++) {
        cout << pop() << endl;
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &aa[i]);
    }
    //quick_sort(aa, 0, n-1);
    //merge_sort(aa, 0, n-1);
    //heap_sort(aa, n);
    sort(aa, aa+n);

    printf("%d\n", aa[n/2]);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值