📜  标记排序(同时获取排序和原始)

📅  最后修改于: 2021-05-05 00:34:45             🧑  作者: Mango

这不是新的排序算法,而是当我们需要避免交换大型对象或需要以原始顺序和排序顺序访问大型数组的元素时的一个主意。
常见的排序任务是使用诸如快速排序,气泡排序等排序算法对数组的元素进行排序,但有时我们需要保持实际数组的完整性并使用“标记的”数组来存储数组中的元素。排序数组时正确放置数组。当我们想以排序方式访问元素时,可以使用此“标记”数组。

为什么要使用标签排序?

当我们对大型对象进行操作时,交换这些大型对象可能会过于昂贵。毕竟,它涉及磁盘交换,我们希望将其最小化!

  • 标记排序允许在用原始对象标记整数数组后对其进行排序。
  • 反过来,我们只交换标签数组的整数,而不交换大型对象的数组。
  • 实际元素在排序过程中不会更改。标签数组中的位置正在更改,因此在对元素进行排序时,它们将保留元素的正确顺序。

在此示例中,arr []中的原始元素未更改,但tag []中的原始元素被操纵。现在,tag []数组将保留arr []中元素的正确下标顺序,因此在调用tag []数组时可以将数组按降序排序。
标签排序

另一个示例,假设我们有以下Person对象,该对象固有地占用大量内存(以GB或数百MB为单位)。

class Person 
{
    private int id;
    private float salary;
    private Object someBigObject = new Object(); 
    public Person(int id, float salary) 
    { }
    public float getSalary() 
    { }
    public String toString() 
    { }
}

因此,在磁盘上寻找交换对象可能会占用大量时间,因此在这些对象之间移动可能不切实际。为了避免这种情况,我们首先创建一个标签数组。

  • 每个Person对象都被标记到tag数组中的一个元素上,而不是交换person对象进行基于薪水的排序,我们交换了tag []整数。
  • 在打印排序后的数组时,我们从标记数组中获取提示以打印排序后的Persons数组。
  • 最终,我们将避免交换大的Persons对象。

以下是上述想法的实现。

// Java Program to illustrate Tag Sort. This code
// uses Bubble Sort to modify tag array according
// to salaries. We can use other optimized sorting
// techniques also.
class Person
{
    private int id;
    private float salary;
    private Object someBigObject = new Object();
  
    public Person(int id, float salary)
    {
        this.id = id;
        this.salary = salary;
    }
  
    public float getSalary()
    {
        return salary;
    }
  
    @Override
    public String toString()
    {
        return "Person{" +
               "id=" + id +
               ", salary=" + salary +
               ", someBigObject=" + someBigObject +
               '}';
    }
}
  
public class Main
{
    public static void main(String[] args)
    {
        // Creating objects and their original
        // order (in tag array)
        int n = 5;
        Person persons[] = new Person[n];
        persons[0] = new Person(0, 233.5f);
        persons[1] = new Person(1, 23f);
        persons[2] = new Person(2, 13.98f);
        persons[3] = new Person(3, 143.2f);
        persons[4] = new Person(4, 3f);
        int tag[] = new int[n];
        for (int i = 0; i < n; i++)
            tag[i] = i;
  
        // Every Person object is tagged to
        // an element in the tag array.
        System.out.println("Given Person and Tag ");
        for (int i = 0; i < n; i++)
            System.out.println(persons[i] +
                               " : Tag: " + tag[i]);
  
        // Modifying tag array so that we can access
        // persons in sorted order.
        tagSort(persons, tag);
  
        System.out.println("New Tag Array after "+
                           "getting sorted as per Person[] ");
        for (int i=0; i
                        persons[tag[j]].getSalary())
                {
                    // Note we are not sorting the
                    // actual Persons array, but only
                    // the tag array
                    int temp = tag[i];
                    tag[i] = tag[j];
                    tag[j] = temp;
                }
            }
        }
    }
}

输出:

Given Person and Tag 
Person{id=0, salary=233.5, someBigObject=java.lang.Object@15db9742} : Tag: 0
Person{id=1, salary=23.0, someBigObject=java.lang.Object@6d06d69c} : Tag: 1
Person{id=2, salary=13.98, someBigObject=java.lang.Object@7852e922} : Tag: 2
Person{id=3, salary=143.2, someBigObject=java.lang.Object@4e25154f} : Tag: 3
Person{id=4, salary=3.0, someBigObject=java.lang.Object@70dea4e} : Tag: 4
New Tag Array after getting sorted as per Person[] 
4
2
1
3
0
Person{id=4, salary=3.0, someBigObject=java.lang.Object@70dea4e}
Person{id=2, salary=13.98, someBigObject=java.lang.Object@7852e922}
Person{id=1, salary=23.0, someBigObject=java.lang.Object@6d06d69c}
Person{id=3, salary=143.2, someBigObject=java.lang.Object@4e25154f}
Person{id=0, salary=233.5, someBigObject=java.lang.Object@15db9742}