日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于递归算法,树形结构数据下业务场景,封装解决方法

發(fā)布時(shí)間:2025/3/16 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于递归算法,树形结构数据下业务场景,封装解决方法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文源碼:GitHub·點(diǎn)這里 || GitEE·點(diǎn)這里

一、遞歸算法

1、概念簡(jiǎn)介

遞歸算法的核心思想是通過將問題重復(fù)分解為同類的或其子問題的方式,從而可以使用統(tǒng)一的解決方式。很多編程語言支持方法或函數(shù)自我調(diào)用,簡(jiǎn)單的說,就是在函數(shù)或方法體內(nèi),自身可以再次調(diào)用自身的方法結(jié)構(gòu)。

2、基礎(chǔ)案例

這里通過遞歸的方式,計(jì)算階乘、求和等相關(guān)邏輯。

public class Demo01 {public static void main(String[] args) {int result1 = factorial(5);System.out.println(result1);int result2 = sum(100) ;System.out.println(result2);}// 遞歸階乘private static int factorial (int n){if(n <= 1){return n ;}else{return n*factorial(n-1);}}// 遞歸求和private static int sum (int f){if(f <= 1){return f ;}else{return f + sum(f-1);}} }

3、注意事項(xiàng)

  • 使用方法

使用遞歸的時(shí)候,要明確業(yè)務(wù)邏輯可以分解為重復(fù)相同的問題,且要清楚的知道遞歸的結(jié)束條件,不然很容易出現(xiàn)死循環(huán)。

  • 優(yōu)缺點(diǎn)描述

遞歸算法的代碼比較簡(jiǎn)潔,可讀性較好;但是在實(shí)際的業(yè)務(wù)處理中會(huì)出現(xiàn)多次的重復(fù)調(diào)用,如果處理不好,很容易出現(xiàn)StackOverflowError報(bào)錯(cuò)。

二、樹狀結(jié)構(gòu)

1、概念描述

樹形結(jié)構(gòu)是一層次的嵌套結(jié)構(gòu)。一個(gè)樹形結(jié)構(gòu)的外層和內(nèi)層有相似的結(jié)構(gòu),所以這種結(jié)構(gòu)多可以遞歸的表示。

2、圖解和定義

  • 根節(jié)點(diǎn)

樹的根源,沒有父節(jié)點(diǎn)的節(jié)點(diǎn),如上圖A節(jié)點(diǎn)。

  • 兄弟節(jié)點(diǎn)

擁有同一父節(jié)點(diǎn)的子節(jié)點(diǎn)。如圖B與C與D節(jié)點(diǎn)。

  • 葉子節(jié)點(diǎn)

沒有子節(jié)點(diǎn)的節(jié)點(diǎn)。如圖E和F等節(jié)點(diǎn)。

  • 分支度

指一個(gè)節(jié)點(diǎn)有幾個(gè)子節(jié)點(diǎn)。 如:A為3、B為2。

  • 節(jié)點(diǎn)深度

指從該節(jié)點(diǎn)到某一節(jié)點(diǎn)的最長(zhǎng)路徑。如圖A為2、B為1。

三、應(yīng)用場(chǎng)景

1、場(chǎng)景描述

基于遞歸算法下,處理很多樹形結(jié)構(gòu)的業(yè)務(wù)數(shù)據(jù)。常見的業(yè)務(wù)場(chǎng)景如下:

  • 省市區(qū)三級(jí)聯(lián)動(dòng)查詢 ;
  • 系統(tǒng)模塊、菜單、按鈕的授權(quán) ;
  • 常見的業(yè)務(wù)數(shù)據(jù)分類:商品分類等 ;
  • 常見各種行業(yè)分類細(xì)化 ;

2、特殊場(chǎng)景

在管理系統(tǒng)中,對(duì)系統(tǒng)模塊、菜單、按鈕授權(quán)操作時(shí)候可能會(huì)出現(xiàn)如下情況。

假如系統(tǒng)管理員的權(quán)限如圖所示,但是給到運(yùn)營(yíng)人員的權(quán)限如下,需要把3號(hào)菜單和5號(hào)菜單設(shè)置為同級(jí)別,這時(shí)候基本的處理手法就是把3號(hào)菜單父級(jí)ID作為3號(hào)菜單和下屬功能的權(quán)限的根節(jié)點(diǎn),這里把這里當(dāng)成兩顆樹進(jìn)行分別處理,最后合并數(shù)據(jù)就好。必要時(shí)按照配上節(jié)點(diǎn)編碼,例如NODE01,NODE0101,NODE0102等方式,這里針對(duì)這個(gè)場(chǎng)景描述,就是希望在處理類似業(yè)務(wù)時(shí)候,思路要開闊,不必拘泥于單個(gè)樹形結(jié)構(gòu)。業(yè)務(wù)很多時(shí)候都是出人意料甚至是令人生厭,不過這確實(shí)就是生活。

3、工具類封裝

這里展示一個(gè)樹形結(jié)構(gòu)常用的幾個(gè)封裝方法,例如創(chuàng)建樹形結(jié)構(gòu),遍歷,判斷等。

import java.util.ArrayList; import java.util.List;public class ThreeUtil {/*** 遞歸創(chuàng)建樹形結(jié)構(gòu)*/private static List<ThreeNode> getTree(List<ThreeNode> nodeList, Integer parentId) {List<ThreeNode> threeNodeList = new ArrayList<>() ;for (ThreeNode entity : nodeList) {Integer nodeId = entity.getId() ;Integer nodeParentId = entity.getParentId() ;if (parentId.intValue() == nodeParentId.intValue()) {List<ThreeNode> childList = getTree(nodeList,nodeId) ;if (childList != null && childList.size()>0){entity.setChildNode(childList);entity.setChildNodeSize(childList.size());}threeNodeList.add(entity) ;}}return threeNodeList ;}/*** 獲取指定子節(jié)點(diǎn)*/private static List<ThreeNode> getChildTree (Integer id,List<ThreeNode> nodeList){List<ThreeNode> resultList = new ArrayList<>();for (ThreeNode entity : nodeList) {if (entity.getParentId().intValue() == id) {List<ThreeNode> childList = getChildTree(entity.getId(),nodeList) ;entity.setChildNode(childList);entity.setChildNodeSize(childList.size());resultList.add(entity) ;}}return resultList ;}/*** 遍歷樹形結(jié)構(gòu)*/private static transient List<Integer> treeIdList = new ArrayList<>() ;private static List<Integer> getTreeInfo (List<ThreeNode> treeList){for (ThreeNode entity : treeList) {if (entity.getChildNodeSize()!=null && entity.getChildNodeSize()>0){getTreeInfo(entity.getChildNode());}treeIdList.add(entity.getId());}return treeIdList ;}/*** 判斷節(jié)是否是葉子節(jié)點(diǎn)*/private static boolean hasChildNode (Integer id,List<ThreeNode> nodeList){for (ThreeNode entity:nodeList){if (entity.getParentId().intValue() == id){return true ;}}return false ;}public static void main(String[] args) {List<ThreeNode> threeNodeList = new ArrayList<>() ;threeNodeList.add(new ThreeNode(1,"節(jié)點(diǎn)A",0)) ;threeNodeList.add(new ThreeNode(2,"節(jié)點(diǎn)B",1)) ;threeNodeList.add(new ThreeNode(3,"節(jié)點(diǎn)C",1)) ;threeNodeList.add(new ThreeNode(4,"節(jié)點(diǎn)D",1)) ;threeNodeList.add(new ThreeNode(5,"節(jié)點(diǎn)E",2)) ;threeNodeList.add(new ThreeNode(6,"節(jié)點(diǎn)F",2)) ;// 測(cè)試1List<ThreeNode> getTree = getTree(threeNodeList,0) ;System.out.println(getTree);// 測(cè)試2// List<ThreeNode> getChildTree = getChildTree(2,threeNodeList) ;// System.out.println(getChildTree);// 測(cè)試3List<Integer> treeIdList = getTreeInfo(getTree) ;System.out.println(treeIdList);// 測(cè)試4System.out.println(hasChildNode(2,threeNodeList)) ;} }

四、源代碼地址

GitHub·地址 https://github.com/cicadasmile GitEE·地址 https://gitee.com/cicadasmile

新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎(jiǎng)!定制產(chǎn)品紅包拿不停!

總結(jié)

以上是生活随笔為你收集整理的基于递归算法,树形结构数据下业务场景,封装解决方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。