[數據結構]二叉搜索樹的代碼實現(C, Java)


出來混總是要還的, 大一的時候沒有好好學習數據結構, 現在要補上了

二叉樹的數據結構

結點

每一個二叉樹的結點中至少含有三個元素, 即結點上的數據, 指向左子樹的指針, 指向右子樹的指針. 假定我們每個結點中的數據整數, 使用c語言描述結點這個數據結構如下

struct node {
	int data;	// 數據域
	struct node* left; // 左指針/孩子
	struct node* right;	// 右指針/孩子
}

對於每一顆樹來說, 我們知道了它的根結點, 就能根據每一個結點上的指針找到它的所有子結點, 也就是說, 找到了它根結點就相當於找到了它的全部結點, 那麼我們就來定義一個樹的數據結構

struct Tree {
	Node* root; // 根節點
}

二叉樹的遍歷

前序遍歷(根->左->右)

前序遍歷, 又稱先序遍歷, 先根遍歷. 對於每一個結點, 先遍歷它的根節點, 然後遍歷它的左孩子結點, 再遍歷右孩子結點, 因此要先把根節點的左子樹全部遍歷完, 纔可以遍歷根結點, 然後是右子樹
那麼用遞歸法肯定是最好的一種方法

void preorder(Node* node) {
	if (node == NULL) { // 遞歸出口
		return ;
	} 
	else {
		printf("%d\n", node -> data);	// 顯示根節點, 相當於遍歷了根節點
		preorder(node -> left);
		preorder(node -> right);
	}
}

中序遍歷(左->根->右)

中序遍歷, 又稱中根遍歷, 即對於每一個結點, 先遍歷其左子樹, 然後遍歷其根節點, 然後遍歷右子樹.
用遞歸方法實現如下

void in_order(Node* node) {
	if (node == NULL) { // 遞歸出口
		return ;	
	}
	else {
		in_order(node -> left);
		printf("%d\n", node -> data);
		in_order(node -> right);
	}
}

後序遍歷(左->右->根)

後續遍歷又稱後根遍歷, 顧名思義就是根在最後一個遍歷, 先遍歷左孩子, 然後遍歷右孩子, 最後遍歷根節點, 遞歸代碼表示如下

void post_order(Node* node) {
	if (node == NULL) {
		return ;
	}
	else {
		post_order(node -> left);
		post_order(node -> right);
		printf("%d \n", node -> data);
	}
}

二叉搜索樹(BST)

二叉搜索樹, (binary search tree)就是一個有序的樹, 其中對於任意一個子樹, 其左孩子中的元素值 小於根節點的元素值 小於右孩子的元素的值, 即,node.left.data < node.right.data , 那麼由我們上面的遍歷方式, 可以看出若使用中序遍歷, 當結點中的元素爲數字時候, 那麼中序遍歷就會是一個從小到大的一個順序,因此二叉搜索樹, 又稱爲二叉排序樹, 那麼我們如何創建一顆二叉搜索樹呢?

插入法創建二叉搜索樹

如果我們將一個元素放在一顆二叉搜索樹中, 首先我們要跟根節點中的元素進行比較, 若小於, 那麼就放在左邊, 繼續跟左邊的結點元素值進行比較, 若大於, 則放在右邊,然後繼續跟右邊的結點元素值進行比較。若爲空, 那麼就放在當前節點。 那麼我們可以對這樣一種方法進行代碼實現

void insert_bst(Tree* tree, int value) {
	Node* node = malloc(sizeof(Node)); // 將這個元素創建爲一個結點
	node -> data = value;
	node -> left = NULL;
	node -> right = NULL;
	
	if (tree -> root == NULL) {
		tree -> root = node;
		return ; // 插入完成之後就停止, 不然程序會一直運行
	}
	else {
		Node* temp = tree -> root;
		while (temp != NULL) {
			if (value < temp -> data) { // 小於當前節點
				if (temp -> left == NULL) {
					temp -> left = node;
					return ; // 插入完成之後就停止, 不然程序會一直運行
				}
				else {
					temp = temp -> left; // 繼續向左搜尋, 比較
				}
			}
			else { // 小於當前結點
				if (temp -> right == NULL) {
					temp -> right = node;
					return ;
				}
				else {
					temp = temp -> right; // 繼續向右
				}
			}
		}
	}
}

測試代碼

#include <stdio.h>
#include <stdlib.h>

typedef struct node {
	int data;
	struct node* left;
	struct node* right;
} Node;

typedef struct {
	Node* root;
} Tree;


void insert_bst(Tree* tree, int value) {
	Node* node = malloc(sizeof(Node));
	node -> data = value;
	node -> left = NULL;
	node -> right = NULL;
	
	if (tree -> root == NULL) {
		tree -> root = node;
		return ;
	}
	else {
		Node* temp = tree -> root;
		while (temp != NULL) {
			if (value < temp -> data) {
				if (temp -> left == NULL) {
					temp -> left = node;
					return ;
				}
				else {
					temp = temp -> left;
				}
			}
			else {
				if (temp -> right == NULL) {
					temp -> right = node;
					return ;
				}
				else {
					temp = temp -> right;
				}
			}
		}
	}
}

void preorder(Node* node) {
	if (node == NULL) {
		return ;
	}
	else {
		printf("%d\n", node -> data);
		preorder(node -> left);
		preorder(node -> right);
	}
}

void in_order(Node* node) {
	if (node == NULL) {
		return ;
	}
	else {
		in_order(node -> left);
		printf("%d\n", node -> data);
		in_order(node -> right);
	}
}

void post_order(Node* node) {
	if (node == NULL) {
		return ;
	}
	else {
		post_order(node -> left);
		post_order(node -> right);
		printf("%d\n", node -> data);
	}
}

int main() {
	int arr[] = {1, 3, 2, 4, 0, 1, 2);
	int length = sizeof(arr) / sizeof(arr[0]);
	
	Tree tree;
	tree.root = NULL;
	
	for (int i = 0; i < length; i++) {
		insert_bst(&tree, arr[i]);
	}
	
	in_order(tree.root);
	return 0;
}

JAVA

Java 代碼與C語言相比沒有什麼太多出入, 我就直接寫一個測試類供大家參考

public class TestTree {

	public static void insert_BST(Tree tree, int value) {
		Node node = new Node(value);

		if (tree.root == null) {
			tree.root = node;
			return;
		} else {
			Node temp = tree.root;
			while (temp != null) {
				if (value < temp.data) {
					if (temp.left == null) {
						temp.left = node;
						return;
					} else {
						temp = temp.left;
					}
				} else {
					if (temp.right == null) {
						temp.right = node;
						return ;
					} else {
						temp = temp.right;
					}
				}
			}
		}
	}
	
	public static void inOrder(Node node) {
		if (node == null) {
			return ;
		} else {
			inOrder(node.left);
			System.out.println(node.data);
			inOrder(node.right);
		}
	}
	
	
	public static void main(String[] args) {
		int[] arr = {5, 8, 2, 1, 4, 3, 9, 7, 6};
		Tree tree = new Tree();
		
		for (int i = 0; i < arr.length; i++) {
			insert_BST(tree, arr[i]);
		}
		
		inOrder(tree.root);
	}
}

class Node {
	int data;
	Node left;
	Node right;

	public Node() {

	}

	public Node(int data) {
		this.data = data;
	}
}

class Tree {
	Node root;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章