首页 > 试题广场 >

自然数数组的排序

[编程题]自然数数组的排序
  • 热度指数:2434 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个长度为N的整形数组arr,其中有N个互不相等的自然数1-N。请实现arr的排序,但是不要把下标位置上的数通过直接赋值的方式替换成
[要求]
时间复杂度为,空间复杂度为 

备注:


输入描述:
第一行有一个整数N。表示数组长度
接下来一行有N个互不相等的自然数1-N。


输出描述:
输出N个整数表示排序后的结果
示例1

输入

5
2 1 4 5 3

输出

1 2 3 4 5 

备注:
没想明白不赋值的话怎么做到时间复杂度O(n)且空间复杂度O(1)。所以干脆偷个懒,反正只要拿到n就已经知道了输出,直接输出答案就好。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine().trim());
        br.readLine();
        for(int num = 1; num <= n; num++)
            System.out.print(num + " ");
    }
}

发表于 2021-06-13 18:24:37 回复(0)
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n, x;
    cin>>n;
    int a[n+1];
    for(int i=0;i<n;i++){
        cin>>x;
        a[x] = x;
    }
    for(int i=1;i<=n;i++)
        cout<<a[i]<<" ";
    return 0;
}

发表于 2020-02-16 00:20:51 回复(1)
import java.util.*;
public class Main{
    public static void main(String arg[]) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] arr = new int[n];
        for (int i=0;i<n;i++) {
            arr[i] = sc.nextInt();
        }
        for (int i=0;i<n;i++) {
            while (arr[i]!=arr[arr[i]-1]) {
                swap(arr, i, arr[i]-1);
            }
            System.out.print(arr[i]+" ");
        }
    }
    public static void swap(int[] arr, int i, int j) {
        if (i==j) return;
        arr[i] = arr[i]^arr[j];
        arr[j] = arr[i]^arr[j];
        arr[i] = arr[i]^arr[j];
    }
}

发表于 2022-07-20 15:49:22 回复(0)
交换
#include "iostream"
#include "vector"

using namespace std;
int main()
{
    int len;
    cin>>len;
    vector<int> nums(len);
    for(int i=0;i<len;i++)
    {
        cin>>nums[i];
    }
    int tmp;
    for(int i=0;i<len;i++)
    {
        while(nums[i]!=i+1)
        {
            tmp=nums[i];
            swap(nums[i],nums[tmp-1]);
        }
        cout<<nums[i]<<' ';
    }
    return 0;
}


发表于 2022-01-12 13:16:57 回复(0)
这个也不能只写一个方法,太麻烦了。
不断交换,直到遍历完一遍。
import java.util.*;
public class Main{
    
    public static void main(String[] args) {
      Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] arr = getArr(n);
        int[] ints = normalSort(arr, n);
        show(ints);
    }
    
    private static int[] normalSort(int[] arr, int n){
        int count = 0;
        while(count < n){
            while (count != arr[count]-1){
                swap(arr,count,arr[count]-1);
            }
            count++;
        }
        return arr;
    }
    private static void swap(int[] arr,int i, int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    
    private static void show(int[] arr){
        for (int i = 0;i<arr.length;i++){
            System.out.print(arr[i]+" ");
        }
    }
    private static int[] getArr(int n){
        int[] arr = new int[n];
        for(int i = n; i > 0; i--){
            arr[n-i] = i;
        }
        return arr;
    }
}


发表于 2021-09-01 20:46:37 回复(0)
#include <iostream>
#include <vector>
using namespace std;

//交换
void swap(vector<int> &v, int i, int j){
    int tmp = v[i];
    v[i] = v[j];
    v[j] = tmp;
}

//冒泡排序
void bubbleSort(vector<int> &v){
    if(v.size() < 2)
        return;
    for(int i = v.size() - 1; i >= 2; i--){
        for(int j = 0; j <= i - 1; j++){
            if(v[j] > v[j + 1])
                swap(v, j, j + 1);
        }
    }
}

//选择排序
void selectSort(vector<int> &v){
    if(v.size() < 2)
        return;
    for(int i = 0; i <= v.size() - 2; i++){
        int minIndex = i;
        for(int j = i + 1; j <= v.size() - 1; j++){
            if(v[j] < v[minIndex])
                minIndex = j;
        }
        swap(v, i, minIndex);
    }
}

//插入排序
void insertSort(vector<int> &v){
    if(v.size() <= 2)
        return;
    for(int i = 1; i <= v.size() - 1; i++){
        for(int j = i - 1; j >= 0 && v[j + 1] < v[j]; j--){
            swap(v, j, j + 1);
        }
    }
}

void merge(vector<int> &v, int l, int mid, int r){
    int p1 = l;
    int p2 = mid + 1;
    vector<int> tmp;
    while(p1 <= mid && p2 <= r){
        if(v[p1] <= v[p2])
            tmp.push_back(v[p1++]);
        else
            tmp.push_back(v[p2++]);
    }
    while(p1 <= mid){
        tmp.push_back(v[p1++]);
    }
    while(p2 <= mid){
        tmp.push_back(v[p2++]);
    }
    for(int i = 0; i < tmp.size(); i++)
        v[i + l] = tmp[i];
}



void mergeProcess(vector<int> &v, int l, int r){
    if(l == r)
        return;
    int mid = l + ((r - l) >> 1);
    mergeProcess(v, l, mid);
    mergeProcess(v, mid + 1, r);
    merge(v, l, mid, r);
}

void mergeSort(vector<int> &v){
    if(v.size() < 2)
        return;
    mergeProcess(v, 0, v.size() - 1);
}


int main(void){
    int n;
    cin >> n;
    vector<int> v(n, 0);
    for(int i = 0; i < n; i++){
        cin >> v[i];
    }
    //bubbleSort(v);
    //selectSort(v);
    //insertSort(v);
    mergeSort(v);
    for(auto vi : v){
        cout << vi << " ";
    }
    cout << endl;
    return 0;
}
总结:在这里实现了冒泡排序、选择排序、插入排序和归并排序。
其中归并排序通过,因为归并排序算法复杂度为0(n * log n)

#include <iostream>
#include <vector>
using namespace std;

void swap(vector<int> &v, int i, int j){
    int tmp = v[i];
    v[i] = v[j];
    v[j] = tmp;
}

//r位置已交换,只负责区分<, ==, >区域
vector<int> partion(vector<int> &v,int l, int r){
    int less = l - 1;
    int more = r;
    while(l < more){
        if(v[l] < v[r]){
            swap(v, ++less, l++);
        }else if(v[l] > v[r]){
            swap(v, --more, l);
        }else{
            l++;
        }
    }
    swap(v, more, r);
    return {less + 1, more};
}

void quickProcess(vector<int> &v, int l, int r){
    if(l >= r)
        return;
    int n = r - l + 1;
    swap(v, r - 1, l + rand() % n);
    vector<int> ans = partion(v, l, r);
    quickProcess(v, l, ans[0] - 1);
    quickProcess(v, ans[0] + 1, r);
}

void quickSort(vector<int> &v){
    if(v.size() < 2)
        return;
    quickProcess(v, 0, v.size() - 1);
}

int main(void){
    int n;
    cin >> n;
    vector<int> v(n, 0);
    for(int i = 0; i < n; i++){
        cin >> v[i];
    }
    quickSort(v);
    for(int i = 0; i < v.size(); i++){
        cout << v[i] << " ";
    }
    cout << endl;
    return 0;
}
这里使用了新的算法 快速排序3.0版本 n足够大为O(n * logn)
编辑于 2021-05-06 18:16:58 回复(0)
const N = Number(readline());
const arr = readline().split(' ').map(Number);
// 长度为N的数组,想要按顺序装入1~N的值
// 排好序后,每个位置上的值和其下标必定满足关系 arr[i] === i + 1;
// 所以遍历原始数组,当遇到不满足 arr[i] === i + 1 条件的,则说明 arr[i] 不应该
// 放在当前的位置 i 上,而是需要移动的,然后就开始移动操作。
let cache; // 缓存当前要移动的数值
let start; // 缓存本轮移动操作是从哪个下标位置开始的
for (let i = 0; i < N; i++) {
  if (arr[i] !== i + 1) {
    cache = arr[i]; // 用cache缓存当前要移动的值
    start = i; // start记录本轮移动开始时的下标位置
    let target = cache - 1; // cache值应该被放在的下标位置
    // 在不断移动的过程中,只要下一个target位置还没有等于本轮移动开始时的start位置,
    // 说明本轮移动过程还没有结束,因为在把各个值放入它应该在的位置的最后,必然会把应该在 start 位置
    // 的值给替换出来,所以当本应该在start位置的值被找到后,直接把它放入start位置,此时就没有还在数组之
    // 外的值,本轮替换才算结束。
    while (target !== start) {
      const tmp = arr[target]; // 替换出当前不应该在target位置的值
      arr[target] = cache; // 把当前要移动的值放在它本应在的target位置
      cache = tmp; // 被替换出的tmp成为下一个要移动的值
      target = cache - 1; // target 也更新为下一个要移动的值,也就是 tmp,本应在的位置
    }
    arr[start] = cache; // 循环结束时,cache中是本应在start位置的值
  }
}
console.log(arr.join(' '));

发表于 2021-03-14 12:54:04 回复(0)
#include<iostream>
using namespace std;
const int N = 1e5+3;
int a[N];


int main() {
    int n;
    scanf("%d", &n);
    for(int i=1;i<=n;++i) scanf("%d", a+i);
    for(int i=1;i<=n;++i) {
        while(a[i]!=i) {
            swap(a[i], a[a[i]]);
        }
        
    }
    for(int i=1;i<=n;++i) {
        printf("%d ", a[i]);
    }
    
    
}

发表于 2021-01-30 22:43:04 回复(0)

这TM有啥好说的???

/*
 * @Description: 自然数数组的排序
 * @Author: 
 * @Date: 2020-11-13 22:03:44
 * @LastEditTime: 2020-11-13 22:10:03
 * @LastEditors: Please set LastEditors
 */
#include<iostream>
#include<vector>
using namespace std;
int main(){

    int N;
    cin >> N;
    vector<int> arr(N + 1);
    int temp;//暂时存放数
    for(int i = 0;i < N;i++){
        cin >> temp;
        arr[temp] = temp;
    }
    for(int i = 1;i < arr.size();i++){
        cout << arr[i] << " ";
    }
    system("pause");
    return 0;
}
发表于 2020-11-13 22:11:10 回复(0)
这题和奇数放在奇数位,偶数放在偶数位的题挺像
//1就是1,2就是2
import java.util.*;


public class Main {
    public static void main(String args[])
    {
        Scanner cin = new Scanner(System.in);
        int n;
        while(cin.hasNextInt())
        {
            n = cin.nextInt();
            int[] a=new int[n];
            for(int i=0;i<n;i++){
                a[i]=cin.nextInt();
            }
            sort(a);
            for(int l:a){
                System.out.print(l+" ");
            }

        }
    }

    public static void sort(int[] a){
        for(int i=0;i<a.length;i++){
            while(a[i]!=i+1){
                swap(a,i,a[i]-1);
            }
        }
    }

    public static void swap(int[] arr,int a,int b){
        int temp=arr[a];
        arr[a]=arr[b];
        arr[b]=temp;
    }
}

发表于 2020-08-15 08:08:49 回复(0)
#include<iostream>
#include<vector>
using namespace std;

int main()
{
    int n,a;
    cin>>n;
    vector<int> arr;
    for(int i=0;i<n;i++)
    {
        cin>>a;
        arr.push_back(a);
    }
    int middle;
    int i=0;                //从0下标开始循环
    while(i<n)
    {
        if(arr[i]==i+1)    //若该数的位置正确,则循环下一个
        {
            i++;
        }
        else
        {
            middle=arr[arr[i]-1];    //若不正确,找到arr[i]数对应的正确位置,交换一下
            arr[arr[i]-1]=arr[i];
            arr[i]=middle;
        }
    }
    for(int i=0;i<n;i++)
    {
        cout<<arr[i];
        cout<<" ";
    }
    return 0;
}



发表于 2019-08-14 21:43:17 回复(0)
kk7头像 kk7
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n;
    cin>>n;
    int tmp[n+1];
    for(int i=0;i<n;i++){
        int num;
        cin>>num;
        tmp[num]=num;
    }
    for(int i=1;i<n+1;i++)
        cout<<tmp[i]<<' ';
    return 0;
}


发表于 2019-08-14 15:18:39 回复(0)
N = eval(input())
ls = list(map(int, input().split()))
ls.sort()
print(' '.join(map(str, ls)))
修改了代码,尝试不用系统函数,却报如下错(连正确通过的代码都报一样的错了)
自测结果
不通过
格式错误:您的程序输出的格式不符合要求(比如空格和换行与要求不一致)
你的输出为:1 2 3 4 5
N = eval(input())
ls = list(map(int, input().split()))
for i in range(N):
    if ls[i] == i+1: # 若位置i上的值为i+1,则位置正确
        continue
    else: # 若位置i上的值不正确时
        i_index = ls.index(i+1) #先确定i+1 的正确位置
        # 将值为i+1的位置与位置i互换
        ls[i], ls[i_index] = ls[i_index], ls[i]
print(' '.join(map(str, ls)))



编辑于 2019-08-13 16:11:49 回复(1)