二叉樹遍歷及應用
阿新 • • 發佈:2018-12-30
二叉樹遍歷
public class BinarayTree { Node<String> root; public BinarayTree(String data){ root=new Node<>(data,null,null); } public void createTree(){ Node<String> nodeB=new Node<String>("B",null,null); Node<String> nodeC=new Node<String>("C",null,null); Node<String> nodeD=new Node<String>("D",null,null); Node<String> nodeE=new Node<String>("E",null,null); Node<String> nodeF=new Node<String>("F",null,null); Node<String> nodeG=new Node<String>("G",null,null); Node<String> nodeH=new Node<String>("H",null,null); Node<String> nodeJ=new Node<String>("J",null,null); Node<String> nodeI=new Node<String>("I",null,null); root.leftChild=nodeB; root.rightChild=nodeC; nodeB.leftChild=nodeD; nodeC.leftChild=nodeE; nodeC.rightChild=nodeF; nodeD.leftChild=nodeG; nodeD.rightChild=nodeH; nodeE.rightChild=nodeJ; nodeH.leftChild=nodeI; } /** * 中序訪問樹的所有節點 */ public void midOrderTraverse(Node root){//邏輯 if(root==null){ return; } midOrderTraverse(root.leftChild);//邏輯 System.out.println("mid:"+root.data);//輸出 midOrderTraverse(root.rightChild);//邏輯 } /** * 前序訪問樹的所有節點 Arrays.sort(); */ public void preOrderTraverse(Node root){ if(root==null){ return; } System.out.println("pre:"+root.data); preOrderTraverse(root.leftChild); preOrderTraverse(root.rightChild); } /** * 後序訪問樹的所有節點 */ public void postOrderTraverse(Node root){ if(root==null){ return; } postOrderTraverse(root.leftChild); postOrderTraverse(root.rightChild); System.out.println("post:"+root.data); } /** * 節點 */ public class Node<T>{ T data; Node<T> leftChild; Node<T> rightChild; public Node(T data, Node<T> leftChild, Node<T> rightChild) { this.data = data; this.leftChild = leftChild; this.rightChild = rightChild; } } }
二分查詢
前題條件:資料已經排序
/** * 二分查詢 */ public static int binarySearch(int[] array,int fromIndex,int toIndex,int key){ int low=fromIndex; int high=toIndex-1; while(low<=high){ int mid=(low+high)/2;//取中間 int midVal=array[mid]; if(key>midVal){//去右邊找 low=mid+1; }else if(key<midVal){//去左邊找 high=mid-1; }else{ return mid; } } return -(low+1);//low+1表示找不到時停在了第low+1個元素的位置 }
快速排序(前序)
應用場景: 資料量大並且是線性結構
缺點:有大量重複資料的時候,效能不好,單向鏈式結構處理效能不好(一般來說,鏈式都不使用)
//快速排序 31 21 59 68 12 40 // x=31 public static void quickSort(int[] array,int begin,int end){ if(end-begin<=0) return; int x=array[begin]; int low=begin;//0 int high=end;//5 //由於會從兩頭取資料,需要一個方向 boolean direction=true; L1: while(low<high){ if(direction){//從右往左找 for(int i=high;i>low;i--){ if(array[i]<=x){ array[low++]=array[i]; high=i; direction=!direction; continue L1; } } high=low;//如果上面的if從未進入,讓兩個指標重合 }else{ for(int i=low;i<high;i++){ if(array[i]>=x){ array[high--]=array[i]; low=i; direction=!direction; continue L1; } } low=high; } } //把最後找到的值 放入中間位置 array[low]=x; //開始完成左右兩邊的操作 quickSort(array,begin,low-1); quickSort(array,low+1,end); }
歸併排序(後序)
應用場景:資料量大並且有很多重複資料,鏈式結構
缺點: 需要空間大
public static void mergeSort(int array[],int left,int right){
if(left==right){
return;
}else{
int mid=(left+right)/2;
mergeSort(array,left,mid);
mergeSort(array,mid+1,right);
merge(array,left,mid+1,right);
}
}
// 0 4 7
// 1 2 5 9 === 3 4 10 11
public static void merge(int[] array,int left,int mid,int right){
int leftSize=mid-left;
int rightSize=right-mid+1;
//生成陣列
int[] leftArray=new int[leftSize];
int[] rightArray=new int[rightSize];
//填充資料
for(int i=left;i<mid;i++){
leftArray[i-left]=array[i];
}
for(int i=mid;i<=right;i++){
rightArray[i-mid]=array[i];
}
//合併
int i=0;
int j=0;
int k=left;
while(i<leftSize && j<rightSize){
if(leftArray[i]<rightArray[j]){
array[k]=leftArray[i];
k++;i++;
}else{
array[k]=rightArray[j];
k++;j++;
}
}
while(i<leftSize){
array[k]=leftArray[i];
k++;i++;
}
while(j<rightSize){
array[k]=rightArray[j];
k++;j++;
}
}