Android遍歷所有控制元件的遞迴和非遞迴實現
題目描述
給出佈局的根節點,要求不使用遞迴的方式將所有型別為Button的控制元件背景設定為紅色。
分析
對於Android中的佈局來說,有兩種型別的節點,一種是ViewGroup佈局,另外一種是View控制元件,按照類似樹形結構來組織(注意,不是二叉樹)。
對於控制元件的遍歷,可以轉化為對樹的遍歷。對樹的遍歷有遞迴方式和非遞迴的方式,非遞迴方式又可以分為深度優先遍歷和廣度優先遍歷。
實現
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rootView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:background="#abcdef"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#156ec7"
android:orientation="horizontal"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="文字1"
android:textColor="#ffffff" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="文字2"
android:textColor="#ffffff" />
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按鈕1" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#5d9726"
android:padding="10dp">
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按鈕2" />
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btn"
android:padding="5dp"
android:text="文字3"
android:textColor="#ffffff"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/btn"
android:layout_toRightOf="@id/tv"
android:padding="5dp"
android:text="文字4"
android:textColor="#ffffff" />
</RelativeLayout>
</LinearLayout>
介面效果和對應的樹結構如下:
其中有顏色的節點型別為viewGroup
佈局 | 抽象樹結構 |
具體演算法實現
以下方式實現了三種方式的遍歷結果,讀者可以參考。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewGroup root = (ViewGroup) findViewById(R.id.rootView);
travelTree3(root);
}
//遞迴遍歷樹
private void travelTree1(View root) {
if (root instanceof ViewGroup) {
int childCount = ((ViewGroup) root).getChildCount();
for (int i = 0; i < childCount; i++) {
travelTree1(((ViewGroup) root).getChildAt(i));
}
} else if (root instanceof View) {
Log.i("visitView", root.toString());
if (root instanceof Button)
root.setBackgroundColor(Color.parseColor("#ff0000"));
}
}
//非遞迴廣度遍歷,利用佇列資料結構
private void travelTree2(View root) {
ArrayDeque queue = new ArrayDeque();
queue.addLast(root);
while (!queue.isEmpty()) {
//取得隊頭
View front = (View) queue.getFirst();
//如果為viewGroup則使子節點入佇列
if (front instanceof ViewGroup) {
int childCount = ((ViewGroup) front).getChildCount();
for (int i = 0; i < childCount; i++) {
queue.addLast(((ViewGroup) front).getChildAt(i));
}
}
//如果隊頭為View型別,輸出
else if (front instanceof View)
Log.i("visitView", front.toString());
//隊頭出隊
queue.pollFirst();
}
}
//非遞迴深度遍歷,利用棧資料結構
private void travelTree3(View root) {
ArrayDeque stack = new ArrayDeque();
stack.addLast(root);
while (!stack.isEmpty()) {
//取得棧頂
View top = (View) stack.getLast();
//出棧
stack.pollLast();
//如果為viewGroup則使子節點入棧
if (top instanceof ViewGroup) {
int childCount = ((ViewGroup) top).getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
stack.addLast(((ViewGroup) top).getChildAt(i));
}
}
//如果棧頂為View型別,輸出
else if (top instanceof View)
Log.i("visitView", top.toString());
}
}
}
相關文章
- 二叉樹的所有遍歷非遞迴實現二叉樹遞迴
- 非遞迴實現先序遍歷和中序遍歷遞迴
- 遍歷二叉樹-------遞迴&非遞迴二叉樹遞迴
- 遍歷二叉樹的遞迴與非遞迴程式碼實現二叉樹遞迴
- [java] 二叉樹的後序遍歷(遞迴與非遞迴實現)Java二叉樹遞迴
- Java遍歷資料夾的兩種方法(非遞迴和遞迴)Java遞迴
- 遞迴遍歷網站所有 url遞迴網站
- 什麼是遍歷二叉樹,JavaScript實現二叉樹的遍歷(遞迴,非遞迴)二叉樹JavaScript遞迴
- 二叉樹的四種遍歷(遞迴與非遞迴)二叉樹遞迴
- 二叉樹的非遞迴遍歷——java實現二叉樹遞迴Java
- python實現二叉樹及其七種遍歷方式(遞迴+非遞迴)Python二叉樹遞迴
- 二叉樹的前中後序遍歷(遞迴和非遞迴版本)二叉樹遞迴
- 【資料結構】二叉樹遍歷(遞迴+非遞迴)資料結構二叉樹遞迴
- 二叉樹非遞迴遍歷二叉樹遞迴
- 資料結構-樹以及深度、廣度優先遍歷(遞迴和非遞迴,python實現)資料結構遞迴Python
- 二叉樹——後序遍歷的遞迴與非遞迴演算法二叉樹遞迴演算法
- 二叉樹建立及遍歷演算法(遞迴及非遞迴)二叉樹演算法遞迴
- 遞迴和非遞迴分別實現求n的階乘遞迴
- 斐波那契數列的遞迴和非遞迴實現遞迴
- 原:八皇后問題的遞迴和非遞迴Java實現遞迴Java
- 非遞迴先序遍歷二叉樹遞迴二叉樹
- 【刷題】二叉樹非遞迴遍歷二叉樹遞迴
- 二叉樹的非遞迴遍歷寫法二叉樹遞迴
- 快速排序【遞迴】【非遞迴】排序遞迴
- js遞迴遍歷講解JS遞迴
- 二分法的簡單實現——-遞迴和非遞迴遞迴
- python-動態規劃的遞迴、非遞迴實現Python動態規劃遞迴
- 遞迴遍歷樹狀結構優雅實現遞迴
- 二叉樹的建立與遍歷(遞迴實現)二叉樹遞迴
- 斐波那契數列(Fibonacci)遞迴和非遞迴實現遞迴
- Java 資料夾遞迴遍歷Java遞迴
- PHP遞迴遍歷資料夾PHP遞迴
- python 遞迴遍歷目錄Python遞迴
- 樹3-二叉樹非遞迴遍歷(棧)二叉樹遞迴
- 歸併排序的非遞迴實現排序遞迴
- 刷題系列 - Python用非遞迴實現二叉樹前序遍歷Python遞迴二叉樹
- Vue3.0的遞迴監聽和非遞迴監聽Vue遞迴
- 遍歷二叉樹的迭代和遞迴方法二叉樹遞迴