検索と並べ替え(1)
検索と並べ替え(2)
検索と並べ替え(4)二分木の探索
import java.util.Scanner;
public class LianXi {
//前序遍历
public static void preOrder(int []arr, int i){
if(i >= arr.length)
return;
System.out.print(arr[i] + " "); //输出根节点
preOrder(arr, 2 * i + 1); //递归输出左子树
preOrder(arr, 2 * i + 2); //递归输出右子树
}
//中序遍历
public static void inOrder(int []arr, int i){
if(i >= arr.length)
return;
inOrder(arr, 2 * i + 1); //递归输出左子树
System.out.print(arr[i] + " "); //输出根节点
inOrder(arr, 2 * i + 2); //递归输出右子树
}
//后序遍历
public static void postOrder(int []arr, int i){
if(i >= arr.length)
return;
postOrder(arr, 2 * i + 1); //递归输出左子树
postOrder(arr, 2 * i + 2); //递归输出右子树
System.out.print(arr[i] + " "); //输出根节点
}
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int []arr = new int[N];
for(int i = 0 ; i<N; i++){
arr[i] = in.nextInt();
}
System.out.println("初始数组为:");
for(int i = 0 ; i<N; i++){
System.out.print(arr[i] + " ");
}
System.out.println("\n");
System.out.println("前序遍历:");
preOrder(arr, 0);
System.out.println("\n");
System.out.println("中序遍历:");
inOrder(arr, 0);
System.out.println("\n");
System.out.println("后序遍历:");
postOrder(arr, 0);
}
}
ヒープ
ヒープの概念
- バイナリヒープは、完全なバイナリツリーまたはほぼ完全なバイナリツリーです。
- バイナリヒープは、次の2つの特性を満たし
ます。1。親ノードのキー値は、常に任意の子ノードのキー値以上(以下)です。
2.各ノードの左右のサブツリーはバイナリヒープです(どちらも最大ヒープまたは最小ヒープです) - 任意のノードの値がその子ノードの値よりも大きい-ビッグトップヒープ
- 任意のノードの値がその子ノードの値よりも小さい-小さなトップヒープ
大顶カセット:arr [i]> = arr [2i + 1] && arr [i]> = arr [2i + 2]
小顶カセット:arr [i] <= arr [2i + 1] && arr [i] <= arr [2i + 2]
ヒープソートヒープソート
の基本的な考え方は次のとおりです:大きなトップヒープにソートされるシーケンスを構築します。現時点では、シーケンス全体の最大値はヒープのトップのルートノードです。最後の要素と交換すると、この時点での最大値はendになります。次に、残りのn-1個の要素をパイルに再構築して、n個の要素の次に小さい値が取得されるようにします。このように繰り返し実行すると、順序付けられたシーケンスを取得できます
手順
1.初期ヒープを作成します。与えられた無秩序なシーケンスを大きなトップパイルに構築します(通常、大きなトップパイルは昇順で使用され、小さなトップパイルは降順で使用されます)。
2.トップ要素とエンド要素を交換して、エンド要素を最大にします。次に、ヒープの調整を続けてから、一番上の要素を最後の要素と交換して、2番目に大きい要素を取得します。このようにして、交換、再構築、交換が繰り返されます。
最小ヒープソート
import java.util.Scanner;
public class LianXi {
/*
* MinHeap(A){
* n = A.length;
* for i from n/2-1 down to 0{
* MinHeapFixDown(A,i,n);
* }
* }
* MinHeapFixDown(A,i,n){
* // 找到左右孩子
* left = 2 * i + 1;
* right = 2 * i + 2;
* //左孩子已经越界,i就是叶子节点
* if(left>=n){
* return;
* }
*
* min = left;
* if(right >= n){
* min = left;
* }
* else{
* if(A[right] < A[left])
* min = right;
*
* }
* //min指向了左右孩子中较小的那个
* //如果A[i]比两个孩子都要小,不用调整
* if(A[i] <= A[min]){
* return ;
* }
* // 否则,找到两个孩子中较小的,和i交换
* swap(A,i,min)
* //小孩子那个位置的值发生了变化,i变更为小孩子那个位置,递归调整
* MinHeapFixDown(A,min,n);
*
* sort(A):
* //先对A进行堆化
* MinHeap(A);
* for(int x = n-1; x>=0; x--)
* //把堆顶,0号元素和最后一个元素对调
* swap(A,0,x);
* //缩小堆的范围,对堆顶元素进行向下调整
* MinHeapFixDown(A,0,x-1)
*/
public static void MinHeap(int []A){
int n = A.length;
for(int i = n/2-1; i>=0; i--){
MinHeapFixDown(A, i, n);
}
}
public static void MinHeapFixDown(int []A, int i, int n){
int left = 2 * i + 1;
int right = 2 * i + 2;
if(left >= n){
return ;
}
int min = left;
if(right >= n){
min = left;
}
else{
if(A[right] < A[left]){
min = right;
}
}
if(A[i] <= A[min]){
return ;
}
swap(A,i,min);
MinHeapFixDown(A, min, n);
}
public static void sort(int []A){
MinHeap(A);
for(int x = A.length-1; x>=0; x--){
swap(A,0,x);
MinHeapFixDown(A, 0, x-1);
}
}
public static void swap(int[]A, int i, int min){
int temp = A[i];
A[i] = A[min];
A[min] = temp;
}
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int N = in.nextInt();
int []A = new int[N];
for(int i = 0; i<N; i++){
A[i] = in.nextInt();
}
System.out.println("初始数组为:");
for(int i = 0; i<N; i++){
System.out.print(A[i]+ " ");
}
System.out.println("\n");
sort(A);
System.out.println("最小堆排序后数组为:");
for(int i = 0; i<N; i++){
System.out.print(A[i] + " ");
}
}
}