이 진 트 리 (BST) 재 귀적 및 비 재 귀적 삽입, 삭제, 검색 의 실현
27116 단어 데이터 구조
BST 의 정의: 만약 에 한 나무의 왼쪽 나무 가 비어 있 지 않 으 면 모든 노드 의 값 은 그 뿌리 노드 의 값 보다 작 습 니 다. 만약 에 오른쪽 나무 가 비어 있 지 않 으 면 모든 노드 의 값 은 그 뿌리 노드 의 값 보다 크 고 그의 좌우 나무 도 상기 성질 을 만족 시 킵 니 다.빈 나무 도 BST.
나의 BST 의 실현 은 중복 요소 가 없 는 것 을 전제 로 하 는데 사실은 중복 요소 가 있어 도 큰 문제 가 없 으 며 실현 과정 에서 관련 된 것 일 뿐이다.
노드 구조 정의:
class Node{
public:
int val;
Node *left, *right;
Node() {}
Node(int val) : val(val), left(NULL), right(NULL) {}
};
BST 구조 정의 및 구현 방법:
class BST{
private:
Node *root;
void Recursion_Insert_Node(Node *&node, int x);//
void Non_Recursion_Insert_Node(Node **node, int x);//
Node *Recursion_Find_Node(Node *node, int x);//
Node *Non_Recursion_Find_Node(Node *root, int x);//
void Delete_Node(Node **root, int x);//
void preOrder_Traverse(Node *root);//
void inOrder_Traverse(Node *root);//
void postOrder_Traversal(Node *root);//
void Delete_BST(Node *node);//
public:
BST();
~BST();
void Create_BST(int *num, int n);// BST
Node *Find_Node(int x);
void Delete_Node(int x);
void preOrder_Traverse();
void inOrder_Traverse();
void postOrder_Traversal();
};
먼저 삽입 결점 이 어떻게 실현 되 는 지 살 펴 보 자. 첫 번 째 로 저장 할 값 에 대해 우 리 는 그것 을 뿌리 결점 으로 설정 한 다음 에 뿌리 결점 보다 작은 값 에 대해 우 리 는 이 를 왼쪽 나무 로 이동 시 킨 다음 에 비교 하고 잎 노드 가 될 때 까지 이동 하면 뿌리 결점 보다 큰 값 이 같다.
구체 적 인 실현:
귀속:
void BST::Recursion_Insert_Node(Node *&node, int x){
if(node == NULL){
node = new Node(x);
}
else if(node->val > x){
Recursion_Insert_Node(node->left, x);
}
else if(node->val < x){
Recursion_Insert_Node(node->right, x);
}
}
비 귀속:
void BST::Non_Recursion_Insert_Node(Node **root, int x){
Node *p = *root;
Node *fa = *root;
while(p){
if(p->val == x){
printf("%d is already exist!
", x);
return;
}
fa = p;
if(p->val > x){
p = p->left;
}
else{
p = p->right;
}
}
if(fa == NULL){
*root = new Node(x);
}
else if(fa->val > x){
fa->left = new Node(x);
}
else{
fa->right = new Node(x);
}
}
재 귀적 이지 않 은 경우 Node 의 유형 은 지침 을 가리 키 는 지침 입 니 다. 지침 만 전달 할 수 없습니다. 지침 만 전달 하고 지침 값 의 복사 가 되면 루트 가 NULL 을 가리 킬 때 함수 내부 new 노드 가 실제 지침 에 의 해 가리 키 지 않 기 때 문 입 니 다.또한 지침 의 인용 도 있어 서 는 안 된다. 왜냐하면 뿌리 결점 을 가리 키 는 지침 이 하위 노드 를 가리 키 기 때문이다.
결점 찾기 의 실현: 사상 은 삽 입 된 것 과 마찬가지 로 지침 을 사용 할 수 있 을 뿐 지침 을 가리 키 는 지침 을 사용 하지 않 습 니 다. 우 리 는 찾 는 요소 의 주소 만 찾 아야 하기 때문에 조작 할 필요 가 없습니다. 지침 을 사용 하면 쉽게 작업 을 완성 할 수 있 습 니 다.
귀속:
Node *BST::Recursion_Find_Node(Node *node, int x){
if(node == NULL)
return NULL;
if(node->val == x)
return node;
if(node->val > x)
return Recursion_Find_Node(node->left, x);
else
return Recursion_Find_Node(node->right, x);
}
비 귀속:
Node *BST::Non_Recursion_Find_Node(Node *node, int x){
if(node == NULL)
return NULL;
while(node){
if(node->val == x)
return node;
else if(node->val > x)
node = node->left;
else
node = node->right;
}
return node;
}
마지막 으로 삭제 작업 입 니 다:
삭제 작업 은 재 귀적 인 쓰기 가 생각 나 지 않 습 니 다...
BST 삭제 작업 에 대해 세 가지 상황 이 있 습 니 다.
1: 노드 를 삭제 하 는 것 이 잎 노드 인 경우 에 가장 좋 습 니 다. 부모 노드 를 비 운 다음 에 이 노드 를 삭제 하면 됩 니 다.
2: 노드 를 삭제 하 는 데 마침 한 가지 가 있 습 니 다. 우 리 는 아버지 노드 를 아들 노드 에 가리 키 기만 하면 됩 니 다. 그리고 delete 를 하면 비교적 간단 합 니 다.
3: 노드 를 삭제 하 는 데 마침 두 개의 갈래 가 있 는데 이런 상황 이 비교적 번 거 롭 고 두 가지 처리 방법 이 있다. 이 두 가지 방법 을 말 하기 전에 우 리 는 먼저 두 가지 개념 을 알 아야 한다. 노드 의 전구: 이 노드 의 최대 노드 보다 작고 전구 에는 오른쪽 서브 트 리 노드 의 후계 가 없다. 이 노드 의 최소 노드 보다 크다.그 다음 에 왼쪽 트 리 가 알 지 못 한 후에 우 리 는 방법 을 논술 할 수 있다. 첫 번 째 방법 은 이 노드 의 앞 구 를 찾 은 다음 에 그의 값 을 삭제 할 노드 에 부여 하고 마지막 으로 이 앞 구 를 삭제 하면 된다.두 번 째 방법 은 첫 번 째 와 유사 하 다. 바로 이 노드 의 후계 자 를 찾 은 다음 에 삭제 할 노드 에 값 을 부여 하고 마지막 으로 이 후계 자 를 삭제 하면 된다.여기 에는 전구 에 오른쪽 트 리 가 없고, 후계 에 왼쪽 트 리 의 특성 이 없 으 니, 구체 적 으로 코드 를 보 세 요.
void BST::Delete_Node(Node **root, int x){
Node *p = *root;
Node *fa = *root;
while(p){
if(p->val == x){
break;
}
fa = p;
if(p->val > x){
p = p->left;
}
else{
p = p->right;
}
}
if(p == NULL){
printf("%d is not found!
", x);
return;
}
if(p->left == NULL && p->right == NULL){// p
if(p == *root){//p
*root = NULL;
}
else if(fa->left == p){
fa->left = NULL;
}
else{
fa->right = NULL;
}
delete p;
}
else if(p->left == NULL || p->right == NULL){// p
if(p == *root){
if(p->left != NULL){
*root = p->left;
}
else{
*root = p->right;
}
}
else{
if(fa->left == p){
if(p->left != NULL){
fa->left = p->left;
}
else{
fa->left = p->right;
}
}
else{
if(p->left != NULL){
fa->right = p->left;
}
else{
fa->right = p->right;
}
}
}
delete p;
}
else{// p
Node *parent = p;
Node *child = p->right;
while(child->left){
parent = child;
child = child->left;
}
p->val = child->val;
if(parent == p){
p->right = child->right;
}
else{
parent->left = child->right;
}
delete child;
}
}
프로그램 총람:
#include
using namespace std;
class Node{
public:
int val;
Node *left, *right;
Node() {}
Node(int val) : val(val), left(NULL), right(NULL) {}
};
class BST{
private:
Node *root;
void Recursion_Insert_Node(Node *&node, int x);//
void Non_Recursion_Insert_Node(Node **node, int x);//
Node *Recursion_Find_Node(Node *node, int x);//
Node *Non_Recursion_Find_Node(Node *root, int x);//
void Delete_Node(Node **root, int x);//
void preOrder_Traverse(Node *root);//
void inOrder_Traverse(Node *root);//
void postOrder_Traversal(Node *root);//
void Delete_BST(Node *node);//
public:
BST();
~BST();
void Create_BST(int *num, int n);// BST
Node *Find_Node(int x);
void Delete_Node(int x);
void preOrder_Traverse();
void inOrder_Traverse();
void postOrder_Traversal();
};
BST::BST(){
this->root = NULL;
}
void BST::Create_BST(int *num, int n){
for(int i = 0; i < n; i++){
// Recursion_Insert_Node(this->root, num[i]);
Non_Recursion_Insert_Node(&this->root, num[i]);
}
}
void BST::Recursion_Insert_Node(Node *&node, int x){
if(node == NULL){
node = new Node(x);
}
else if(node->val > x){
Recursion_Insert_Node(node->left, x);
}
else if(node->val < x){
Recursion_Insert_Node(node->right, x);
}
}
void BST::Non_Recursion_Insert_Node(Node **root, int x){
Node *p = *root;
Node *fa = *root;
while(p){
if(p->val == x){
printf("%d is already exist!
", x);
return;
}
fa = p;
if(p->val > x){
p = p->left;
}
else{
p = p->right;
}
}
if(fa == NULL){
*root = new Node(x);
}
else if(fa->val > x){
fa->left = new Node(x);
}
else{
fa->right = new Node(x);
}
}
void BST::Delete_Node(int x){
Delete_Node(&this->root, x);
}
void BST::Delete_Node(Node **root, int x){
Node *p = *root;
Node *fa = *root;
while(p){
if(p->val == x){
break;
}
fa = p;
if(p->val > x){
p = p->left;
}
else{
p = p->right;
}
}
if(p == NULL){
printf("%d is not found!
", x);
return;
}
if(p->left == NULL && p->right == NULL){// p
if(p == *root){//p
*root = NULL;
}
else if(fa->left == p){
fa->left = NULL;
}
else{
fa->right = NULL;
}
delete p;
}
else if(p->left == NULL || p->right == NULL){// p
if(p == *root){
if(p->left != NULL){
*root = p->left;
}
else{
*root = p->right;
}
}
else{
if(fa->left == p){
if(p->left != NULL){
fa->left = p->left;
}
else{
fa->left = p->right;
}
}
else{
if(p->left != NULL){
fa->right = p->left;
}
else{
fa->right = p->right;
}
}
}
delete p;
}
else{// p
Node *parent = p;
Node *child = p->right;
while(child->left){
parent = child;
child = child->left;
}
p->val = child->val;
if(parent == p){
p->right = child->right;
}
else{
parent->left = child->right;
}
delete child;
}
}
Node *BST::Find_Node(int x){
// return Recursion_Find_Node(this->root, x);
return Non_Recursion_Find_Node(this->root, x);
}
void BST::preOrder_Traverse(){
preOrder_Traverse(this->root);
}
void BST::inOrder_Traverse(){
inOrder_Traverse(this->root);
}
void BST::postOrder_Traversal(){
postOrder_Traversal(this->root);
}
Node *BST::Recursion_Find_Node(Node *node, int x){
if(node == NULL)
return NULL;
if(node->val == x)
return node;
if(node->val > x)
return Recursion_Find_Node(node->left, x);
else
return Recursion_Find_Node(node->right, x);
}
Node *BST::Non_Recursion_Find_Node(Node *node, int x){
if(node == NULL)
return NULL;
while(node){
if(node->val == x)
return node;
else if(node->val > x)
node = node->left;
else
node = node->right;
}
return node;
}
void BST::preOrder_Traverse(Node *root){
if(root != NULL){
printf("%d ", root->val);
preOrder_Traverse(root->left);
preOrder_Traverse(root->right);
}
}
void BST::inOrder_Traverse(Node *root){
if(root != NULL){
inOrder_Traverse(root->left);
printf("%d ", root->val);
inOrder_Traverse(root->right);
}
}
void BST::postOrder_Traversal(Node *root){
if(root != NULL){
postOrder_Traversal(root->left);
postOrder_Traversal(root->right);
printf("%d ", root->val);
}
}
void BST::Delete_BST(Node *node){
if(node == NULL)
return;
if(node->left != NULL)
Delete_BST(node->left);
if(node->right != NULL)
Delete_BST(node->right);
delete node;
}
BST::~BST(){
Delete_BST(this->root);
}
int main()
{
return 0;
}
코드 같은 거 말 하지 마 세 요. T.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.