溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

基于Java遞歸算法的封裝解決方法是什么

發(fā)布時間:2021-11-03 17:57:38 來源:億速云 閱讀:168 作者:iii 欄目:編程語言

本篇內(nèi)容介紹了“基于Java遞歸算法的封裝解決方法是什么”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

一、遞歸算法

1、概念簡介

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

2、基礎(chǔ)案例

這里通過遞歸的方式,計算階乘、求和等相關(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、注意事項

  • 使用方法

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

  • 優(yōu)缺點描述

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

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

1、概念描述

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

2、圖解和定義

基于Java遞歸算法的封裝解決方法是什么

  • 根節(jié)點

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

  • 兄弟節(jié)點

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

  • 葉子節(jié)點

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

  • 分支度

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

  • 節(jié)點深度

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

三、應(yīng)用場景

1、場景描述

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

  • 省市區(qū)三級聯(lián)動查詢 ;

  • 系統(tǒng)模塊、菜單、按鈕的授權(quán) ;

  • 常見的業(yè)務(wù)數(shù)據(jù)分類:商品分類等 ;

  • 常見各種行業(yè)分類細(xì)化 ;

2、特殊場景

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

基于Java遞歸算法的封裝解決方法是什么

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

3、工具類封裝

這里展示一個樹形結(jié)構(gòu)常用的幾個封裝方法,例如創(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é)點
     */
    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é)點
     */
    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é)點A",0)) ;
        threeNodeList.add(new ThreeNode(2,"節(jié)點B",1)) ;
        threeNodeList.add(new ThreeNode(3,"節(jié)點C",1)) ;
        threeNodeList.add(new ThreeNode(4,"節(jié)點D",1)) ;
        threeNodeList.add(new ThreeNode(5,"節(jié)點E",2)) ;
        threeNodeList.add(new ThreeNode(6,"節(jié)點F",2)) ;
        // 測試1
        List<ThreeNode> getTree = getTree(threeNodeList,0) ;
        System.out.println(getTree);
        // 測試2
        // List<ThreeNode> getChildTree = getChildTree(2,threeNodeList) ;
        // System.out.println(getChildTree);
        // 測試3
        List<Integer> treeIdList = getTreeInfo(getTree) ;
        System.out.println(treeIdList);
        // 測試4
        System.out.println(hasChildNode(2,threeNodeList)) ;
    }
}

“基于Java遞歸算法的封裝解決方法是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI