樹結構中的節點增刪改操作後,排序碼的重新設定
阿新 • • 發佈:2019-02-05
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 + "]";
}
}