Open In App

Tag Sort (To get both sorted and original)

Last Updated : 02 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

This is not a new sorting algorithm, but an idea when we need to avoid swapping of large objects or need to access elements of a large array in both original and sorted orders. A common sorting task is to sort elements of an array using a sorting algorithm like Quick Sort, Bubble Sort.. etc, but there may be times when we need to keep the actual array in tact and use a “tagged” array to store the correct positioning of the array when it is sorted. When we want to access elements in sorted way, we can use this “tagged” array.

Why to use Tag Sort?

When we are operating on large array of objects, it might be too costly to swap these large object. After all its about the disk swaps and we want to minimize it!

  • Tag Sort allows sorting an integer array after tagging it with original object.
  • In turn, we only swap the tag array integers instead of large array of objects.
  • The actual elements are not being changed during the sort process. The positions in the tag array are being changed so they will hold the correct ordering of the elements when they are sorted.

In this example, the original elements in arr[] are not changed, but the original elements in tag[] are manipulated. The tag[] array will now hold the correct subscript ordering of the elements in arr[] so the array can be sorted into descending order when the tag[] array is called upon. Tag Sort 

Another Example, Suppose we have following Person object which inherently takes large chunk of memory( in GB or hundreds of 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()
{ }
}

Hence, it might not be practical to move around these objects as disk seeks for swaps can eat up a lot of time. To avoid this, we start by creating a tag array.

  • Every Person object is tagged to one element in the tag array and Instead of swapping the person object for sorting based on salary , we swap the tag[] integers.
  • While printing the sorted array we take a cue from the tag array to print the sorted Persons array.
  • Eventually, we’ll escape swapping large Persons object.

Below is the implementation of above idea. 

C++




#include <iostream>
#include <vector>
 
class Person {
private:
    int id;
    float salary;
    int someBigObject;
 
public:
    Person(int id, float salary)
        : id(id), salary(salary), someBigObject(0) {}
 
    float getSalary() {
        return salary;
    }
 
    // The toString method in C++ can be replaced with the friend ostream operator overloading.
    friend std::ostream& operator<<(std::ostream& os, const Person& person) {
        os << "Person{" << "id=" << person.id << ", salary=" << person.salary << ", someBigObject=" << person.someBigObject << "}";
        return os;
    }
};
 
void tagSort(std::vector<Person>& persons, std::vector<int>& tag) {
    int n = persons.size();
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (persons[tag[i]].getSalary() > persons[tag[j]].getSalary()) {
                // Note that we are not sorting the actual Persons array, but only the tag array
                int temp = tag[i];
                tag[i] = tag[j];
                tag[j] = temp;
            }
        }
    }
}
 
int main() {
    // Creating objects and their original order (in tag vector)
    int n = 5;
    std::vector<Person> persons;
    persons.push_back(Person(0, 233.5f));
    persons.push_back(Person(1, 23.0f));
    persons.push_back(Person(2, 13.98f));
    persons.push_back(Person(3, 143.2f));
    persons.push_back(Person(4, 3.0f));
 
    std::vector<int> tag(n);
    for (int i = 0; i < n; i++) {
        tag[i] = i;
    }
 
    // Every Person object is tagged to an element in the tag vector.
    std::cout << "Given Person and Tag " << std::endl;
    for (int i = 0; i < n; i++) {
        std::cout << persons[i] << " : Tag: " << tag[i] << std::endl;
    }
 
    // Modifying the tag vector so that we can access persons in sorted order.
    tagSort(persons, tag);
 
    std::cout << "New Tag Array after getting sorted as per Person[]" << std::endl;
    for (int i = 0; i < n; i++) {
        std::cout << tag[i] << std::endl;
    }
 
    // Accessing persons in sorted (by salary) way using the modified tag vector.
    for (int i = 0; i < n; i++) {
        std::cout << persons[tag[i]] << std::endl;
    }
 
    return 0;
}


Java




// 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<n; i++)
            System.out.println(tag[i]);
 
        // Accessing persons in sorted (by salary)
        // way using modified tag array.
        for (int i = 0; i < n; i++)
            System.out.println(persons[tag[i]]);
    }
 
    // Modifying tag array so that we can access
    // persons in sorted order of salary.
    public static void tagSort(Person persons[],
                            int tag[])
    {
        int n = persons.length;
        for (int i=0; i<n; i++)
        {
            for (int j=i+1; j<n; j++)
            {
                if (persons[tag[i]].getSalary() >
                        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;
                }
            }
        }
    }
}


Python3




class Person:
    def __init__(self, id, salary):
        self.id = id
        self.salary = salary
        self.someBigObject = object()
 
    def getSalary(self):
        return self.salary
 
    def __str__(self):
        return "Person{" + "id=" + str(self.id) + ", salary=" + str(self.salary) + ", someBigObject=" + str(self.someBigObject) + "}"
 
def tagSort(persons, tag):
    n = len(persons)
    for i in range(n):
        for j in range(i+1, n):
            if persons[tag[i]].getSalary() > persons[tag[j]].getSalary():
                # Note we are not sorting the actual Persons array, but only the tag array
                tag[i], tag[j] = tag[j], tag[i]
 
if __name__ == '__main__':
    # Creating objects and their original order (in tag array)
    n = 5
    persons = [Person(0, 233.5), Person(1, 23), Person(2, 13.98), Person(3, 143.2), Person(4, 3)]
    tag = [i for i in range(n)]
 
    # Every Person object is tagged to an element in the tag array.
    print("Given Person and Tag")
    for i in range(n):
        print(str(persons[i]) + " : Tag: " + str(tag[i]))
 
    # Modifying tag array so that we can access persons in sorted order.
    tagSort(persons, tag)
 
    print("New Tag Array after getting sorted as per Person[]")
    for i in range(n):
        print(tag[i])
 
    # Accessing persons in sorted (by salary) way using modified tag array.
    for i in range(n):
        print(persons[tag[i]])


C#




using System;
 
public 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;
    }
 
    public override string ToString()
    {
        return "Person{" +
            "id=" + id +
            ", salary=" + salary +
            ", someBigObject=" + someBigObject +
            '}';
    }
}
 
public class MainClass
{
    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.
        Console.WriteLine("Given Person and Tag ");
        for (int i = 0; i < n; i++)
            Console.WriteLine(persons[i] +
                            " : Tag: " + tag[i]);
 
        // Modifying tag array so that we can access
        // persons in sorted order.
        TagSort(persons, tag);
 
        Console.WriteLine("New Tag Array after " +
                        "getting sorted as per Person[] ");
        for (int i=0; i<n; i++)
            Console.WriteLine(tag[i]);
 
        // Accessing persons in sorted (by salary)
        // way using modified tag array.
        for (int i = 0; i < n; i++)
            Console.WriteLine(persons[tag[i]]);
    }
 
    // Modifying tag array so that we can access
    // persons in sorted order of salary.
    public static void TagSort(Person[] persons, int[] tag)
    {
        int n = persons.Length;
        for (int i=0; i<n; i++)
        {
            for (int j=i+1; j<n; j++)
            {
                if (persons[tag[i]].GetSalary() >
                        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;
                }
            }
        }
    }
}


Javascript




// Javascript 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
{
    constructor(id,salary)
    {
        this.id = id;
        this.salary = salary;
    }
 
    getSalary()
    {
        return this.salary;
    }
 
    // @Override
    toString()
    {
        return "Person{"+"id=" + this.id +", salary=" + this.salary +'}';
    }
}
 
 
        // Creating objects and their original
        // order (in tag array)
         
          
        var n=5;
        var persons0 = new Person(0, 233.5);
        var persons1 = new Person(1, 23.0);
        var persons2 = new Person(2, 13.98);
        var persons3 = new Person(3, 143.2);
        var persons4 = new Person(4, 3.0);
        var persons=[persons0,persons1,persons2,persons3,persons4];
 
 
        var tag =[];
        for (var i = 0; i<n; i++){
            tag[i] = i;
        }
        // Every Person object is tagged to
        // an element in the tag array.
         
        console.log("Given Person and Tag");
        for (var i = 0; i<n; i++){
            console.log(persons[i] +" : Tag: "+ tag[i]);
        }
        // Modifying tag array so that we can access
        // persons in sorted order.
        tagSort(persons, tag);
 
        console.log("New Tag Array after"+
                           "getting sorted as per Person[]");
        for (var i=0; i<n; i++)
            console.log(tag[i]);
 
        // Accessing persons in sorted (by salary)
        // way using modified tag array.
        for (var i = 0; i<n; i++)
            console.log(persons[tag[i]]);
     
 
    // Modifying tag array so that we can access
    // persons in sorted order of salary.
    function tagSort(persons,tag)
    {
        var n = persons.length;
        for (var i=0; i<n; i++)
        {
            for (var j=i+1; j<n; j++)
            {
                if (persons[tag[i]].getSalary() > persons[tag[j]].getSalary())
                {
                    // Note we are not sorting the
                    // actual Persons array, but only
                    // the tag array
                    var temp = tag[i];
                    tag[i] = tag[j];
                    tag[j] = temp;
                }
            }
        }
    }


Output

Given Person and Tag 
Person{id=0, salary=233.5, someBigObject=java.lang.Object@52cc8049} : Tag: 0
Person{id=1, salary=23.0, someBigObject=java.lang.Object@5b6f7412} : Tag: 1
Person{id=2, salary=13.98, someBigObject=java.lang.Object@27973e9b} : Tag: 2
Person{id=3, salary=143.2, someBigObject=java.lang.Object@312b1dae} : Tag: 3
Person{id=4, salary=3.0, someBigObject=java.lang.Object@7530d0a} : 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@7530d0a}
Person{id=2, salary=13.98, someBigObject=java.lang.Object@27973e9b}
Person{id=1, salary=23.0, someBigObject=java.lang.Object@5b6f7412}
Person{id=3, salary=143.2, someBigObject=java.lang.Object@312b1dae}
Person{id=0, salary=233.5, someBigObject=java.lang.Object@52cc8049}



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads