A. DS排序--希尔排序
题目描述
给出一个数据序列,使用希尔排序算法进行降序排序。
间隔gap使用序列长度循环除2直到1
输入
第一行输入t,表示有t个测试示例
第二行输入n,表示第一个示例有n个数据(n>1)
第三行输入n个数据,都是正整数,数据之间用空格隔开
2
6
111 22 6 444 333 55
8
77 555 33 1 444 77 666 2222
以此类推
输出
对每组测试数据,输出每趟排序结果。不同组测试数据间用空行分隔。
444 333 55 111 22 6
444 333 111 55 22 6
444 555 666 2222 77 77 33 1
666 2222 444 555 77 77 33 1
2222 666 555 444 77 77 33 1
解析:希尔排序是什么?
希尔排序原理:
希尔排序属于插入类排序,是 将整个有序序列分割成若干小的子序列 分别进行 插入排序。
具体原理可看下图:
按照一定的规则,将数组分为多个组,然后每个组分别进行插入排序。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
int t;
cin>>t;
while (t--){
int n;
cin>>n;
int arr[100];
for (int i = 0; i < n; ++i) {
cin>>arr[i];
}
int gap=n/2;
while (gap>=1){
for (int i = 0; i < n; ++i) {
int ii=i;vector<int>v;
if(ii+gap<n){
while (ii<n){
v.push_back(arr[ii]);
ii+=gap;
}
sort(v.rbegin(),v.rend());ii-=gap;
while (!v.empty()){
arr[ii]=v.back();
v.pop_back();
ii-=gap;
}
}
}
for (int i = 0; i < n-1; ++i) {
cout<<arr[i]<<" ";
}cout<<arr[n-1]<<endl;
gap/=2;
}cout<<endl;
}
}
B. DS排序--直接插入排序
题目描述
给出一个数据序列,使用直接插入排序算法进行升序排序。
输入
第一行输入t,表示有t个测试示例
第二行输入n,表示第一个示例有n个数据(n>1)
第三行输入n个数据,都是正整数,数据之间用空格隔开
以此类推
2
5
111 22 6 444 333
6
21 25 49 25 16 8
输出
对每组测试数据,输出每趟排序结果。不同组测试数据间用空行分隔。
22 111 6 444 333
6 22 111 444 333
6 22 111 444 333
6 22 111 333 444
21 25 49 25 16 8
21 25 49 25 16 8
21 25 25 49 16 8
16 21 25 25 49 8
8 16 21 25 25 49
解析:直接插入排序(Straight Insertion Sort)是一种最简单的排序方法,其基本操作是将一条记录插入到已排好的有序表中,从而得到一个新的、记录数量增1的有序表。
每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从后向前扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。(此处没设置哨兵)
时间复杂度为:O(n²)
#include <iostream>
using namespace std;
void Print(int array[], int length) { //自定义输出函数,每执行一次打印一次序列
for (int i = 0; i < length; i++) {
cout << array[i];
if (i!=length - 1)
{
cout << " ";
}
}
cout << endl;
}
void InsertSort(int array[], int length) {
for (int i = 1; i < length; i++) { //第1个数是有序的,所以从第2个数开始遍历,依次插入
int j = i - 1; //前i-1个数都是有序序列(由小到大),只要a[j]比temp大,就将此数后移
int temp = array[i];
for (j = i - 1; j >= 0 && array[j] > temp; j--) {//a[j]小于 temp 时循环结束,结束后应将 temp 赋值给a[j+1]
array[j + 1] = array[j]; //将 a[j] 后移一位
}
array[j + 1] = temp; //将 temp 赋值给a[j+1]
Print(array, length);
}
}
int main() {
int t;
cin >> t;
while (t--)
{
int n;
cin >> n;
int* array = new int[n];
for (int i = 0; i < n; i++)
{
cin >> array[i];
}
//Print(array, n); //先打印原始序列
InsertSort(array, n);
cout << endl;
}
return 0;
}
C. DS内排—直插排序
题目描述
给定一组数据,使用直插排序完成数据的升序排序。
--程序要求--
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求
输入
数据个数n,n个数据
7 34 23 677 2 1 453 3
输出
直插排序的每一趟排序结果
23 34 677 2 1 453 3
23 34 677 2 1 453 3
2 23 34 677 1 453 3
1 2 23 34 677 453 3
1 2 23 34 453 677 3
1 2 3 23 34 453 677
#include <iostream>
using namespace std;
void Print(int array[], int length) { //自定义输出函数,每执行一次打印一次序列
for (int i = 0; i < length; i++) {
cout << array[i];
if (i!=length - 1)
{
cout << " ";
}
}
cout << endl;
}
void InsertSort(int array[], int length) {
for (int i = 1; i < length; i++) { //第1个数是有序的,所以从第2个数开始遍历,依次插入
int j = i - 1; //前i-1个数都是有序序列(由小到大),只要a[j]比temp大,就将此数后移
int temp = array[i];
for (j = i - 1; j >= 0 && array[j] > temp; j--) {//a[j]小于 temp 时循环结束,结束后应将 temp 赋值给a[j+1]
array[j + 1] = array[j]; //将 a[j] 后移一位
}
array[j + 1] = temp; //将 temp 赋值给a[j+1]
Print(array, length);
}
}
int main() {
int n;
cin >> n;
int* array = new int[n];
for (int i = 0; i < n; i++)
{
cin >> array[i];
}
//Print(array, n); //先打印原始序列
InsertSort(array, n);
cout << endl;
return 0;
}
D. 冒泡排序
题目描述
给定一个包含从0到n-1各一次的数组,若使用冒泡排序将其排为升序,问其中需要进行多少次交换
输入
测试数据有多组,
每组由两行组成:第一行包含正整数n(n <= 5000); 下一行包含从0到n-1的n个整数的序列。
10
1 3 6 9 0 8 5 7 4 2
输出
对于每组测试数据,
输出交换次数
22
解析:
AC代码
#include <iostream>
#include <cstdio>
using namespace std;
void bubble_sort(int * arr, int len)
{
int i, j;
int k = 0;
for (i = 0; i < len - 1; i++)
for (j = 0; j < len - 1 - i; j++)
if (arr[j] > arr[j + 1])
{
swap(arr[j], arr[j + 1]);
k++;
}
cout << k << endl;
}
int main() {
int t;
while(scanf("%d",&t)!=EOF)
{
int* arr = new int[t];
for (int i = 0; i < t; i++)
{
cin >> arr[i];
}
bubble_sort(arr, t);
}
}
E. DS排序—快速排序
题目描述
输入一组数据,用快速排序进行升序排序。
输入
测试次数t
每组测试数据为:
数据个数n,n个数字
输出
对每组测试数据,输出快速排序每趟排好的数字及位置(位置从1开始)。不同组测试数据的输出以空行分隔。
快排板子
#include <iostream>
using namespace std;
void quick_sort(int *arry,int low,int high)
{
if(low>=high)
return;
int i=low-1,j=high+1,x=arry[low+high>>1];
while(i<j)
{
do i++;while(arry[i]<x);
do j--;while(arry[j]>x);
if(i<j) swap(arry[i],arry[j]);
}
quick_sort(arry,low,j);
quick_sort(arry,j+1,high);
}
int main()
{
int num[10]={12,56,96,1,-1,32,56,4,89,5};
quick_sort(num,0,9);
for(int i=0;i<10;i++)
printf("%d ",num[i]);
}
AC代码
#include <iostream>
using namespace std;
int n;
int Partition(int *a, int low, int high) {
int pivot = a[low];
while (low < high) {
while (low < high && a[high] >= pivot)
high--;
a[low] = a[high];
while (low < high && a[low] < pivot)
low++;
a[high] = a[low];
}
a[high] = pivot;
cout << pivot << ' ' << high << endl;
return high;
}
void QuickSort(int *a, int low, int high) {
if (low <= high) {
int pivotpos = Partition(a, low, high);
QuickSort(a, low, pivotpos - 1);
QuickSort(a, pivotpos + 1, high);
}
}
int main() {
int t;
cin >> t;
while (t--) {
cin >> n;
int *a = new int[n + 1];
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
QuickSort(a, 1, n);
cout << endl;
delete[]a;
}
cout << endl;
return 0;
}
F. 快速排序
题目描述
给出一个数据序列,使用快速排序算法进行从小到大的排序
--程序要求--
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求
输入
第一行输入t,表示有t个测试示例
第二行输入n,表示第一个示例有n个数据
第三行输入n个数据,都是正整数,数据之间用空格隔开
2
6
111 22 6 444 333 55
8
77 555 33 1 444 77 666 2222
以此类推
输出
每组测试数据,输出每趟快排的结果,即每次排好一个数字结果(长度为1的子序列,不用排,不用输出)。不同测试数据间用空行分隔。
55 22 6 111 333 444
6 22 55 111 333 444
6 22 55 111 333 444
6 22 55 111 333 444
1 33 77 555 444 77 666 2222
1 33 77 555 444 77 666 2222
1 33 77 77 444 555 666 2222
1 33 77 77 444 555 666 2222
1 33 77 77 444 555 666 2222
#include<iostream>
using namespace std;
int n;
int Partition(int * &array, int low, int high){
int mid_key= array[low];//记录枢轴的值
while(low< high){
while(low< high&&array[high]>= mid_key )
high--;
array[low]= array[high];//大于枢轴的值前移
while(low< high&&array[low]<= mid_key)
low++;
array[high]= array[low]; //小于枢轴的值后移
}
array[low]= mid_key;//最后才将枢轴的值记录到位
return low; //返回枢轴的位置
}
void print(int * &array){//打印输出
for(int i= 1; i<= n; i++){
cout<<array[i];
if(i!= n)
cout<<' ';
else
cout<<endl;
}
}
void Qsort(int* &array, int low, int high){//快速排序
if(low< high){
int mid= Partition(array, low, high);
print(array);
Qsort(array, low, mid- 1);//将数组分成[low,mid-1]和[mid,high]两个区间
Qsort(array, mid+ 1, high);//
}
}
int main(){
int t;
cin>>t;
while(t--){
cin>>n;
int *array= new int [n+ 5];
for(int i= 1; i<= n; i++)
cin>>array[i];
int low= 1;
int high= n;
Qsort(array, low, high);
delete []array;
cout<<endl;
}
return 0;
}