Open In App

Tag Sort (To get both sorted and original)

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!

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.  

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.

Below is the implementation of above idea. 




#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 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;
                }
            }
        }
    }
}




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]])




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 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}


Article Tags :