Показать сообщение отдельно
Старый 13.01.2015, 09:35   #17
Жека
Дэвелопер
 
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,376
Написано 491 полезных сообщений
(для 886 пользователей)
Ответ: Смесь: Неочевидное + Оптимизация

Замутил удобоваримые для мозга сортировки образов внутри объектов.

Образы сортируются сначала по глубине depth - это слой рисования: -1 задний, 0 средний, 1 передний; затем по addOrder - порядку добавления образа в объект.

Т.к. я отказался от массивов в пользу списков, то пришлось переделывать сортировку.
Вот что получилось.

LinkedList.sortBubble()
public void sortBubble(final IComparator comparator) {
    if(
count 2) { return; }
    
boolean dirty true;
    while(
dirty) {
        
Link node1 first;
        
Link node2 node1.next;
        
dirty false;
        while(
true) {
            
int r comparator.compare(node1.itemnode2.item);
            if(
0) {
                
Object tmp node1.item;
                
node1.item node2.item;
                
node2.item tmp;
                
dirty true;
            }
            
node1 node2;
            
node2 node2.next;
            if(
node2 == null) {
                break;
            }
        }
    }




Было:
public static void sortViews_Depth_AddOrder(final View views[]) {
    if(
views.length 2) { return; }
    
int max;
    
int valprev=0;
    
View tmp;
    final 
int mas[] = new int[views.length];
    
int index 0;
    
//сортировка по depth
    
for(int k views.length ; ++k) {
        
max views[k].depth();
        for(
int j k+views.length ; ++j) {
            
val views[j].depth();
            if(
val max) {
                
tmp views[j];
                
views[j] = views[k];
                
views[k] = tmp;
                
max val;
            }
        }
        if(
&& max != prev)
            ++
index;
        ++
mas[index];
        
prev max;
    }
    
//сортировка по addOrder
    
index 0;
    
int end 0;
    for(
int k views.length ; ++, ++index) {
        if(
mas[index] < 2//если один с таким значением, то он уже на своём месте
            
continue;
        
end k+mas[index];
        for(
int j end ; ++j) {
            
max views[j].addOrder();
            for(
int i j+end ; ++i) {
                
val views[i].addOrder();
                if(
val max) {
                    
tmp views[i];
                    
views[i] = views[j];
                    
views[j] = tmp;
                    
max val;
                }
            }
        }
    }


здесь в массив mas (писал ещё в те времена, когда массивы называл mas, а не arr) накапливаем количество одинаковых чисел, идущих подряд, чтобы потом отсортировать среди них по addOrder.

рекламный слоган: "Тройной FOR - это по-нашему!"

Стало:
private static DepthAddOrderComparator depthAddOrderComparator;
public static 
void sortViews_Depth_AddOrder(final LinkedList views) {
    if(
views.count() < 2) { return; }
    if(
depthAddOrderComparator == null) {
        
depthAddOrderComparator = new DepthAddOrderComparator();
    }
    
views.sortBubble(depthAddOrderComparator);



А вот наш чудесный "комплексный" компаратор, который включает в себя сравнение по двум параметрам - depth и addOrder.
public class DepthAddOrderComparator implements IComparator {

    public 
int compare(Object o1Object o2) {
        
ViewObject vo1 = (ViewObject)o1;
        
ViewObject vo2 = (ViewObject)o2;
        
View v1 vo1.view();
        
View v2 vo2.view();
        
int d1 v1.depth();
        
int d2 v2.depth();
        if(
d1 == d2) {
            
//если глубина одинакова, то нужно сортировать по очерёдности добавления
            
int a1 v1.addOrder();
            
int a2 v2.addOrder();
            if(
a1 == a2) {
                return 
0;
            } else if(
a1 a2) {
                return 
1;
            } else {
                return -
1;
            }
        } else if(
d1 d2) {
            return 
1;
        } else {
            return -
1;
        }
    }




Добавление условий
if(d1 == d2) {
    
//если глубина одинакова, то нужно сортировать по очерёдности добавления
    
int a1 v1.addOrder();
    
int a2 v2.addOrder();
    if(
a1 == a2) {
        return 
0;
    } else if(
a1 a2) {
        return 
1;
    } else {
        return -
1;
    }

позволяет избавиться от монстра в виде
//сортировка по addOrder
index 0;
int end 0;
for(
int k views.length ; ++, ++index) {
    if(
mas[index] < 2//если один с таким значением, то он уже на своём месте
        
continue;
    
end k+mas[index];
    for(
int j end ; ++j) {
        
max views[j].addOrder();
        for(
int i j+end ; ++i) {
            
val views[i].addOrder();
            if(
val max) {
                
tmp views[i];
                
views[i] = views[j];
                
views[j] = tmp;
                
max val;
            }
        }
    }

(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо Жека за это полезное сообщение:
Randomize (14.01.2015), St_AnGer (13.01.2015)