java深度優先演算法
Ⅰ 在線等,計算機高手,java深度搜索樹代碼
有一本書,是講JAVA數據結構的,裡面有很多樹的講解和例子,二叉樹什麼的,還有樹的遍歷,都有例子,建議去看一下
Ⅱ java 深度優先搜索(回溯法)求集合的冪集
import java.util.ArrayList;
import java.util.List;
public class BackTrack {
public static void main(String[] args) {
//初始化一個集合,放在list裡面
List<String> list=new ArrayList<String>();
list.add("1");
list.add("2");
list.add("3");
list.add("f");
List<String> li=new ArrayList<String>();
PowerSet(0,list,li);
}
//回溯法求冪集
public static void PowerSet(int i,List<String> list,List<String> li){
if(i>list.size()-1){System.out.println(li);}
else{
li.add(list.get(i));//左加
PowerSet(i+1,list,li); //遞歸方法
li.remove(list.get(i)); //右去
PowerSet(i+1, list, li);
}
}
}
註:該方法採用中序遍歷二叉樹(實際這棵樹是不存在的)。對於第一個元素,左節點加進去,右節點去掉。對於第i一個節點,左加,右去。直到i大於元素的總個數。
輸出結果:
[1, 2, 3, 4]
[1, 2, 3]
[1, 2, 4]
[1, 2]
[1, 3, 4]
[1, 3]
[1, 4]
[1]
[2, 3, 4]
[2, 3]
[2, 4]
[2]
[3, 4]
[3]
[4]
[]
Ⅲ java如何實現 深度優先 廣度優先
下面是我修改了滴源碼,是基於一張簡單的地圖,在地圖上搜索目的節點,依次用深度優先、廣度優先、Dijkstra演算法實現。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Stack;
/**
*
* @author yinzhuo
*
*/
public class Arithmatic {
boolean flag = true;
// 一張地圖
static int[][] map = new int[][]// 地圖數組
{
{ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0 },
{ 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0 },
{ 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
{ 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
Ⅳ 用java編寫 深度優先法 尋路時 怎麼實現八個方向的路徑選擇
//循環遍歷八個方向:
for(int dx = -1; dx <= 1; dx++) {
for(int dy = -1; dy <= 1; dy++) {
//向x方向移動dx,向y方向移動dy
int nx = x+dx, ny = y + dy;
if()//這里是你要查找的滿足條件的元素
}
}
Ⅳ 大學java中都學過哪些經典演算法請學過的朋友解答下
¤ 歸並排序演算法
¤ 枚舉法
¤ 數字全排列問題
¤ 優化高精度減法
¤ 高精度階乘
¤ 高精度減法
¤ 高精度乘法
¤ Dijkstra最短路徑(一點到各頂點最短路徑)
¤ 八皇後問題
¤ 快速排序演算法
¤ 地圖四色問題
¤ 穿越迷宮
¤ 常用排序演算法
¤ 二分查找法完整版
¤ 標准快速排序演算法
¤ 一躺快速排序法
¤ 快速排序演算法
¤ 插入排序演算法
¤ 選擇排序演算法
¤ 冒泡排序演算法
¤ 統計演算法
¤ 常用演算法——廣度優先搜索
¤ 常用演算法——深度優先搜索
Ⅵ java面試題 很急 謝謝
2, 歸並排序(merge sort)體現了分治的思想,即將一個待排序數組分為兩部分,對這兩個部分進行歸並排序,排序後,再對兩個已經排序好的數組進行合並。這種思想可以用遞歸方式很容易實現。歸並排序的時間復雜度為O(nlogn),空間復雜度為O(n)。
實現代碼如下:
#include <stdio.h>
#include "common.h"
void merge(int data[], int p, int q, int r)
{
int i, j, k, n1, n2;
n1 = q - p + 1;
n2 = r - q;
int L[n1];
int R[n2];
for(i = 0, k = p; i < n1; i++, k++)
L[i] = data[k];
for(i = 0, k = q + 1; i < n2; i++, k++)
R[i] = data[k];
for(k = p, i = 0, j = 0; i < n1 && j < n2; k++)
{
if(L[i] > R[j])
{
data[k] = L[i];
i++;
}
else
{
data[k] = R[j];
j++;
}
}
if(i < n1)
{
for(j = i; j < n1; j++, k++)
data[k] = L[j];
}
if(j < n2)
{
for(i = j; i < n2; i++, k++)
data[k] = R[i];
}
}
void merge_sort(int data[], int p, int r)
{
if(p < r)
{
int q = (p + r) / 2;
merge_sort(data, p, q);
merge_sort(data, q + 1, r);
merge(data, p, q, r);
}
}
void test_merge_sort()
{
int data[] = {44, 12, 145, -123, -1, 0, 121};
printf("-------------------------------merge sort----------------------------\n");
out_int_array(data, 7);
merge_sort(data, 0, 6);
out_int_array(data, 7);
}
int main()
{
test_merge_sort();
return 0;
}
4.對於有n個結點的線性表(e0,e1,…,en-1),將結點中某些數據項的值按遞增或遞減的次序,重新排列線性表結點的過程,稱為排序。排序時參照的數據項稱為排序碼,通常選擇結點的鍵值作為排序碼。
若線性表中排序碼相等的結點經某種排序方法進行排序後,仍能保持它們在排序之前的相對次序,稱這種排序方法是穩定的;否則,稱這種排序方法是不穩定的。
在排序過程中,線性表的全部結點都在內存,並在內存中調整它們在線性表中的存儲順序,稱為內排序。在排序過程中,線性表只有部分結點被調入內存,並藉助內存調整結點在外存中的存放順序的排序方法成為外排序。
下面通過一個表格簡單介紹幾種常見的內排序方法,以及比較一下它們之間的性能特點。
排序方法
簡介
平均時間
最壞情況
輔助存儲
是否穩定
簡單排序
選擇排序
反復從還未排好序的那部分線性表中選出鍵值最小的結點,並按從線性表中選出的順序排列結點,重新組成線性表。直至未排序的那部分為空,則重新形成的線性表是一個有序的線性表。
O( )
O( )
O(1)
不穩定
直接插入排序
假設線性表的前面I個結點序列e0,e1,…,en-1是已排序的。對結點在這有序結點ei序列中找插入位置,並將ei插入,而使i+1個結點序列e0,e1,…,ei也變成排序的。依次對i=1,2,…,n-1分別執行這樣的插入步驟,最終實現線性表的排序。
O( )
O( )
O(1)
穩定
冒泡排序
對當前還未排好序的范圍內的全部結點,自上而下對相鄰的兩個結點依次進行比較和調整,讓鍵值大的結點往下沉,鍵值小的結點往上冒。即,每當兩相鄰比較後發現它們的排列順序與排序要求相反時,就將它們互換。
O( )
O( )
O(1)
穩定
希爾排序
對直接插入排序一種改進,又稱「縮小增量排序」。先將整個待排序列分割成為若乾子序列分別進行直接插入排序,待整個序列中的記錄「基本有序」時,再對全體記錄進行一次直接插入排序。
kn ln n
O( )
O(logn)
不穩定
快速排序
對冒泡排序的一種本質的改進。通過一趟掃視後,使待排序序列的長度能大幅度的減少。在一趟掃視後,使某個結點移到中間的正確位置,並使在它左邊序列的結點的鍵值都比它的小,而它右邊序列的結點的鍵值都不比它的小。稱這樣一次掃視為「劃分」。每次劃分使一個長序列變成兩個新的較小子序列,對這兩個小的子序列分別作同樣的劃分,直至新的子序列的長度為1使才不再劃分。當所有子序列長度都為1時,序列已是排好序的了。
O(nlogn)
O( )
O(logn)
不穩定
堆排序
一種樹形選擇排序,是對直接選擇排序的有效改進。一個堆是這樣一棵順序存儲的二叉樹,它的所有父結點(e[i])的鍵值均不小於它的左子結點(e[2*i+1])和右子結點(e[2*i+2])的鍵值。初始時,若把待排序序列的n個結點看作是一棵順序存儲的二叉樹,調整它們的存儲順序,使之成為一個堆,這時堆的根結點鍵值是最大者。然後將根結點與堆的最後一個結點交換,並對少了一個結點後的n-1結點重新作調整,使之再次成為堆。這樣,在根結點得到結點序列鍵值次最大值。依次類推,直到只有兩個結點的堆,並對它們作交換,最後得到有序的n個結點序列。
O(nlogn)
O(nlogn)
O(1)
不穩定
歸並排序
將兩個或兩個以上的有序子表合並成一個新的有序表。對於兩個有序子表合並一個有序表的兩路合並排序來說,初始時,把含n個結點的待排序序列看作有n個長度都為1的有序子表所組成,將它們依次兩兩合並得到長度為2的若干有序子表,再對它們作兩兩合並……直到得到長度為n的有序表,排序即告完成。
O(nlogn)
O(nlogn)
O(n)
穩定
後面根據各種排序演算法,給出了C語言的實現,大家在復習的時候可以做下參考。
u 選擇排序
void ss_sort(int e[], int n)
{ int i, j, k, t;
for(i=0; i< n-1; i++) {
for(k=i, j=i+1; j<n; j++)
if(e[k]>e[j]) k=j;
if(k!=i) {
t=e[i]; e[i]=e[k]; e[k]=t;
}
}
}
u 直接插入排序
void si_sort(int e[], int n)
{ int i, j, t;
for(i=0; i< n; i++) {
for(t=e[i], j=i-1; j>=0&&t<e[j]; j--)
e[j+1]=e[j];
e[j+1]=t;
}
}
u 冒泡排序
void sb_sort(int e[], int n)
{ int j, p, h, t;
for(h=n-1; h>0; h=p) {
for(p=j=0; j<h; j++)
if(e[j]>e[j+1]) {
t=e[j]; e[j]=e[j+1]; e[j+1]=t;
p=j;
}
}
}
u 希爾排序
void shell(int e[], int n)
{ int j, k, h, y;
for(h=n/2; h>0; h=h/2)
for(j=h; j<n; j++) {
y=e[j];
for(k=j-h; k>0&&y<e[k]; k-=h)
e[k+h]=e[k];
e[k+h]=y;
}
}
u 堆排序
void sift(e, n, s)
int e[];
int n;
int s;
{ int t, k, j;
t=e[s];
k=s; j=2*k+1;
while(j<n) {
if(j<n-1&&e[j]<e[j+1])
j++;
if(t<e[j]) {
e[k]=e[j];
k=j;
j=2*k+1;
}else break;
}
e[k]=t;
}
void heapsorp (int e[], int n)
{ int i, k, t;
for(i=n/2-1; i>=0; i--)
sift(e, n, i);
for(k=n-1; k>=1; k--) {
t=e[0]; e[0]=e[k]; e[k]=t;
sift(e, k, 0);
}
}
u 快速排序
void r_quick(int e[], int low, int high)
{ int i, j, t;
if(low<high) {
i=low; j=high; t=e[low];
while(i<j) {
while (i<j&&e[j]>t) j--;
if(i<j) e[I++]=e[j];
while (i<j&&e[i]<=t) i++;
if(I<j) e[j--]=e[i];
}
e[i]=t;
r_quick(e,low,i-1);
r_quick(w,i+1,high);
}
}
另外,外排序是對大型文件的排序,待排序的記錄存儲在外存中,在排序過程中,內存只存儲文件的一部分記錄,整個排序過程需進行多次的內外存間的交換。
*** 查找
查找就是在按某種數據結構形式存儲的數據集合中,找出滿足指定條件的結點。
按查找的條件分類,有按結點的關鍵碼查找、關鍵碼以外的其他數據項查找或其他數據項的組合查找等。按查找數據在內存或外存,分內存查找和外存查找。按查找目的,查找如果只是為了確定指定條件的結點存在與否,成為靜態查找;查找是為確定結點的插入位置或為了刪除找到的結點,稱為動態查找。
這里簡單介紹幾種常見的查找方法。
u 順序存儲線性表的查找
這是最常見的查找方式。結點集合按線性表組織,採用順序存儲方式,結點只含關鍵碼,並且是整數。如果線性表無序,則採用順序查找,即從線性表的一端開始逐一查找。而如果線性表有序,則可以使用順序查找、二分法查找或插值查找。
u 分塊查找
分塊查找的過程分兩步,先用二分法在索引表中查索引項,確定要查的結點在哪一塊。然後,再在相應塊內順序查找。
u 鏈接存儲線性表的查找
對於鏈接存儲線性表的查找只能從鏈表的首結點開始順序查找。同樣對於無序的鏈表和有序的鏈表查找方法不同。
u 散列表的查找
散列表又稱雜湊表,是一種非常實用的查找技術。它的原理是在結點的存儲位置和它的關鍵碼間建立一個確定的關系,從而讓查找碼直接利用這個關系確定結點的位置。其技術的關鍵在於解決兩個問題。
I. 找一個好的散列函數
Ⅶ 深度優先遍歷的過程
設x是當前被訪問頂點,在對x做過訪問標記後,選擇一條從x出發的未檢測過的邊(x,y)。若發現頂點y已訪問過,則重新選擇另一條從x出發的未檢測過的邊,否則沿邊(x,y)到達未曾訪問過的y,對y訪問並將其標記為已訪問過;然後從y開始搜索,直到搜索完從y出發的所有路徑,即訪問完所有從y出發可達的頂點之後,才回溯到頂點x,並且再選擇一條從x出發的未檢測過的邊。上述過程直至從x出發的所有邊都已檢測過為止。此時,若x不是源點,則回溯到在x之前被訪問過的頂點;否則圖中所有和源點有路徑相通的頂點(即從源點可達的所有頂點)都已被訪問過,若圖G是連通圖,則遍歷過程結束,否則繼續選擇一個尚未被訪問的頂點作為新的頂點,繼續遍歷。
template <int max_size>void Digraph<max_size> :: depth_first(void (*visit)(Vertex &)) const
/* Post: The function *visit has been performed at each vertex of the Digraph in depth-first order.
Uses: Method traverse to proce the recursive depth-first order. */
{
bool visited [max_size];
Vertex v;
for (all v in G) visited [v] = false;
for (all v in G) if (!visited [v])
traverse (v, visited, visit);
}
template <int max_size>
void Digraph<max_size>::traverse(Vertex &v, bool visited[ ],void (*visit)(Vertex &)) const
/* Pre: v is a vertex of the Digraph.
Post: The depth-first traversal, using function *visit, has been completed for v and for all vertices that can be reached from v.
Uses: traverse recursively. */
{
Vertex w;
visited [v] = true;
(*visit) (v);
for (all w adjacent to v)
if (!visited [w])
traverse (w, visited, visit);
}
java代碼如下://求DFS的深度優先遞歸演算法public class DNFSreach {
/*** 這里是文檔說明* 演算法如下*開始*Start;** procere DFS_visit(G,u)* color[u] = Gray;//白色結點u已被發現* for each edge (u,v)do* if color[u] = White then* DFS_visit(G,v);* repeat color[u]=black;//完成後置u為黑色 * end;* * procere DFS(G)* for each vertex u 屬於V do* color[u] = white* for vertex each u 屬於 V do* if color[u]=white* then DFS_visit(G,u)* repeat* * * 構建一個無向圖* 無窮大表示這兩個點無邊,1表示兩者有邊* 白色用1表示,灰色用2表示,黑色用3表示* 初始狀態均為白色* 搜索中被發現的頂點置為灰色* 結束時,即其鄰接表被完全檢索之後,其被置為黑色* 構建一個color[8]數組,其中color[0]不用* 初始化為0* S表示無窮大* 0 1 2 3 4 5 6 7 8* -------------------------* 0 * 1 s 1 1 s s s s s* 2 1 s s 1 1 s s s* 3 1 s s s s 1 1 s* 4 s 1 s s s s s 1* 5 s 1 s s s s s 1* 6 s s 1 s s s 1 s* 7 s s 1 s s 1 s s* 8 s s s 1 1 s s s* * 深度優先搜索的結果應該為* 1-2-4-8-5-3-6-7* * @param args*/static int color[];static int d =0;public static void main(String[] args) {int s = Integer.MAX_VALUE;int G[][]={{s,s,s,s,s,s,s,s,s},{s,s,1,1,s,s,s,s,s},{s,1,s,s,1,1,s,s,s},{s,1,s,s,s,s,1,1,s},{s,s,1,s,s,s,s,s,1},{s,s,1,s,s,s,s,s,1},{s,s,s,1,s,s,s,1,s},{s,s,s,1,s,s,1,s,s},{s,s,s,s,1,1,s,s,s}};color = new int [9];ProcereDFS(G,9);}public static void ProcereDFS(int [][]G,int n){//圖是以二維數組的形式保存//n是二維數組的維數for(int i=1;i <= n-1;i++){color[i]=1;//把每一個頂點都置為白色,表示還沒搜索}for(int i=1;i<= n-1;i++){//對於每一個頂點沒被訪問的頂點進行訪問if(color[i] == 1){DFS_visit(G,i);//遍歷其訪問的頂點}}}
private static void DFS_visit(int[][] g, int i) {// TODO 自動生成的方法存根color[i] = 2;//標志為灰色,表示被訪問過d++;if(d != g.length-1)System.out.print(+i+ -> );if(d == g.length-1){System.out.println(+i);}for(int t=1;t<= g.length-1;t++){//鄰接點沒有被訪問到if(color[t] == 1 && g[i][t] != Integer.MAX_VALUE){DFS_visit(g,t);}}color[i] = 3;//標志位黑色}}
Ⅷ (急)編寫一個java工程,隨機自動生成一個迷宮,並分別運用廣度優先和深度優先算出入口到出口的路徑
Ⅸ 深度優先和廣度優先 的區別 ,用法。
1、主體區別
深度優先搜索是一種在開發爬蟲早期使用較多的方法。它的目的是要達到被搜索結構的葉結點(即那些不包含任何超鏈的HTML文件)。
寬度優先搜索演算法(又稱廣度優先搜索)是最簡便的圖的搜索演算法之一,這一演算法也是很多重要的圖的演算法的原型。
2、演算法區別
深度優先搜索是每次從棧中彈出一個元素,搜索所有在它下一級的元素,把這些元素壓入棧中。並把這個元素記為它下一級元素的前驅,找到所要找的元素時結束程序。
廣度優先搜索是每次從隊列的頭部取出一個元素,查看這個元素所有的下一級元素,把它們放到隊列的末尾。並把這個元素記為它下一級元素的前驅,找到所要找的元素時結束程序。
3、用法
廣度優先屬於一種盲目搜尋法,目的是系統地展開並檢查圖中的所有節點,以找尋結果。換句話說,它並不考慮結果的可能位置,徹底地搜索整張圖,直到找到結果為止。
深度優先即在搜索其餘的超鏈結果之前必須先完整地搜索單獨的一條鏈。深度優先搜索沿著HTML文件上的超鏈走到不能再深入為止,然後返回到某一個HTML文件,再繼續選擇該HTML文件中的其他超鏈。
(9)java深度優先演算法擴展閱讀:
實際應用
BFS在求解最短路徑或者最短步數上有很多的應用,應用最多的是在走迷宮上,單獨寫代碼有點泛化,取來自九度1335闖迷宮一例說明,並給出C++/Java的具體實現。
在一個n*n的矩陣里走,從原點(0,0)開始走到終點(n-1,n-1),只能上下左右4個方向走,只能在給定的矩陣里走,求最短步數。n*n是01矩陣,0代表該格子沒有障礙,為1表示有障礙物。
int mazeArr[maxn][maxn]; //表示的是01矩陣int stepArr = {{-1,0},{1,0},{0,-1},{0,1}}; //表示上下左右4個方向,int visit[maxn][maxn]; //表示該點是否被訪問過,防止回溯,回溯很耗時。核心代碼。基本上所有的BFS問題都可以使用類似的代碼來解決。
Ⅹ 圖的深度優先遍歷Java演算法
圖的深度優先搜索的非遞歸版本演算法的兩種實現,很詳細
http://blog.csdn.net/EmilMatthew/archive/2006/01/17/582381.aspx