1. 程式人生 > >樹結構中的節點增刪改操作後,排序碼的重新設定

樹結構中的節點增刪改操作後,排序碼的重新設定

package com.naydog.sort.bysortkey;

import java.util.ArrayList;
import java.util.List;

/**
 * 目的:樹結構中一個節點下的子節點非自然排序,而是按照排序碼。當發生節點增刪,或位置移動時,需要重新設定排序碼
 * 此為重新設定排序碼的演算法實現
 */
public class SortBySortKey {

    /**
     * 步長,相鄰節點之間排序碼相差10,即排序碼是0,10,20,30...,而非0,1,2,3...
     */
    private int SORT_STEP = 10;

    /**
     * 
     * @param
id * @param newPid 新的父節點 * @param position 插入的位置 */
public void update(String id, String newPid, int position) { // 從repository獲得物件 E entity = null;//repository.findById(id); String oldPid = entity.getPid(); entity.setPid(newPid); entity.setSortKey(position * SORT_STEP - 1
); // 這裡設定為步長的整數倍少一點很重要,在後面排序的時候可少傳一些引數,少一些判斷 // 儲存到repository // repository.save(entity); // 重新設定排序碼 if (!oldPid.equals(newPid)) { // 換了父節點,原先所在父節點也需要重排序 sortBySortKey(oldPid); } sortBySortKey(newPid); } /** * 重新設定某一節點下子節點的排序碼。分四種情況: * 原排序碼: * 0, 10, 20, 30, 40 * 插入後待排序的排序碼(插入到第三個 +19): * 0, 10, 19, 20, 30, 40 直接重新按步長設定排序碼 * 移除後待排序的排序碼(移除第三個 -20): * 0, 10, 30, 40 直接重新按步長設定排序碼 * 從右往左移後待排序的排序碼(第四個移到第二個 -30 +9): * 0, 9, 10, 20, 40 直接重新按步長設定排序碼 * 從左往右移動後待排序的排序碼 (第二個移到第四個 -10 +29): * 0, 20, 29, 30, 40 29和30應該交換順序,然後按步長設定排序碼 * * @param
pid */
public void sortBySortKey(String pid) { // 某父節點下所有子節點(包括新插入的節點) List<E> siblings = null; //repository.findByPid(pid); // 只需要對增加節點之後的節點重新設定排序碼 int unmatch = 0; boolean flag = false; List<E> needsSortList = new ArrayList<>(); for (int i = 0; i < siblings.size(); i++) { E entity = siblings.get(i); if (entity.getSortKey() != i * SORT_STEP) { // 排序碼和索引不一致,需要處理 unmatch++; // 若第一個不匹配的數大於預期排序碼(i*步長)則說明是刪除或者是從左向右移動節點,標記之 if (unmatch == 1 && entity.getSortKey() > i * SORT_STEP) { flag = true; } // 當設定了flag後,發現不能被步長整除的節點則表示當前為向右移的節點,此時要同時更新i與i+1 節點 if (flag && (entity.getSortKey()) % SORT_STEP != 0 //當前為插入/修改位置的節點 && i < siblings.size() - 1) { // 後面還有節點 entity.setSortKey((i + 1) * SORT_STEP); // 兩者要交換順序 needsSortList.add(entity); E tmpCtg2 = siblings.get(i + 1); tmpCtg2.setSortKey(i * SORT_STEP); // 兩者要交換順序 needsSortList.add(tmpCtg2); unmatch++; i++; } else { // 其餘情況直接修改為步長的整數倍即可 entity.setSortKey(i * SORT_STEP); needsSortList.add(entity); } } } // 更新 //repository.saveAll(needsSortList); } public static void main(String[] args) { } } /** * 節點 */ class E { private String id; private String pid; private int sortKey; public E(String id, String pid, int sortKey) { this.id = id; this.pid = pid; this.sortKey = sortKey; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getPid() { return pid; } public void setPid(String pid) { this.pid = pid; } public int getSortKey() { return sortKey; } public void setSortKey(int sortKey) { this.sortKey = sortKey; } @Override public String toString() { return "E [id=" + id + ", pid=" + pid + ", sortKey=" + sortKey + "]"; } }