以下三种排序算法的时间复杂度是 O(n^2)。在这三种排序算法中,比较好的是插入排序。
基本思想:假设前 i 个元素已经排好序,然后把第 i+1 个元素插入到合适的位置上。
- void ins_sort(int *a, int start, int end)
- {
- int j,k;
- for (int i=start+1; i<end; i++)
- {
- for (k=a[i],j=i-1; k<a[j] && j>=start; j--)
- a[j+1]=a[j];
- a[j+1]=k;
- }
- }
基本思想:处理第 i 个元素时,找到它后面所有数的最小值。如果这个最小值比它小,就互相交换。
- void swap_sort(int *a, int start, int end)
- {
- int temp;
- for (int i=start; i<end; i++)
- for (int j=i+1; j<end; j++)
- if (a[i]>a[j])
- temp=a[i],a[i]=a[j],a[j]=temp;
- }
基本思想:对相邻两个元素进行比较,并将较小的数放到前面。重复 n 组即可完成排序。
- void bubble_sort(int *a, int start, int end)
- {
- int temp;
- for (int i=start; i<end; i++)
- for (int j=end; j>i; j--) // 从start到i,在“冒泡”过程中,元素已经排好序。
- if (a[j-1]>a[j])
- temp=a[j-1], a[j-1]=a[j], a[j]=temp;
- }
以下几种排序算法的时间复杂度为 O(n),因为它们使用的是基于数字本身的排序。
基本思想:设计 M 个桶,根据元素本身进行分配。因为 M 个桶是按顺序排列的,所以分配元素之后元素也会按顺序排列。
待排序的数据范围不太大时可以考虑这样排序(比如1~1000可以考虑,而1~100000就必须用快速排序)。
下面假设每个数都位于区间[1, M]。
- int cnt[M];
- memset(cnt,0,sizeof(cnt));
- for (int i=0; i<N; i++)
- cnt[a[i]]++;
- // 从cnt[0]开始挨个列举就行了。例如
- for (int i=0; i<M; i++)
- while ((cnt[i]--)>0)
- cout<<i<<" ";
基本思想:对于序列中的每一元素 x,确定序列中小于 x 的元素的个数。下面假设每个数都位于区间[1, m]。
- int a[N], b[N], cnt[M];
- ……
- memset(cnt,0,sizeof(cnt));
- for (int i=0;i<n;i++) cnt[a[i]]++;
- for (int i=1;i<M;i++) cnt[i]+=cnt[i-1];
- for (int i=n-1;i>0;i--)
- {
- b[cnt[a[i]]] = a[i];
- cnt[a[i]]--;
- }
- // 输出结果
- for (int i=0;i<n;i++) cout<<b[i]<<' ';
基本思想:对 n 个元素依次按 k,k-1,...1 位上的数字进行桶排序。
- int tmp[N], cnt[10];
- int n;
- int maxbit(int *data, int n) // 辅助函数,求数据的最大位数
- {
- int d = 1; // 保存最大的位数
- int p =10;
- for (int i = 0;i < n; i++)
- while (data[i] >= p)
- p *= 10, d++;
- return d;
- }
- void radixsort(int *data, int n) // 基数排序
- {
- int d = maxbit(data,n);
- int i,j,k;
- int radix = 1;
- for (i = 1; i<= d;i++) // 进行d次排序
- {
- for (j = 0;j < 10;j++)
- cnt[j] = 0; // 每次分配前清空计数器
- for (j = 0;j < n; j++)
- {
- k = (data[j]/radix)%10; // 统计每个桶中的记录数
- cnt[k]++;
- }
- for (j = 1;j < 10;j++)
- cnt[j] = cnt[j-1] + cnt[j]; // 将tmp中的位置依次分配给每个桶
- for (j = n-1;j >= 0;j--) // 将所有桶中记录依次收集到tmp中
- {
- k = (data[j]/radix)%10;
- cnt[k]--;
- tmp[cnt[k]] = data[j];
- }
- for (j = 0;j < n;j++) // 将临时数组的内容复制到data中
- data[j] = tmp[j];
- radix = radix*10;
- }
- }