1. 程式人生 > >[C語言實現]實現二叉查詢樹基本操作(遞迴版,圖示)

[C語言實現]實現二叉查詢樹基本操作(遞迴版,圖示)

定義

二叉查詢樹是一種特殊的二叉樹,它不僅是一顆二叉樹,還滿足如下性質

對於任何非葉子節點,他的左節點都小於它本身,而右節點都大於其本身.
它的左右子樹也分別而二叉搜尋樹

一般情況下,在這麼一棵樹中進行查詢,它的時間複雜度是 longn
但是在最壞情況下,一棵樹會退化成單鏈表,那麼此時的查詢時間複雜度就是 n

實現

標頭檔案

#pragma once
#include<stdio.h>
typedef char SearchTreeType;
typedef struct SearchTreeNode
{
  SearchTreeType key;
  struct
SearchTreeNode* lchild; struct SearchTreeNode* rchild; }SearchTreeNode; void SearchTreeInit(SearchTreeNode** root,SearchTreeType key); void SearchTreeInsert(SearchTreeNode** root, SearchTreeType key); SearchTreeNode* SearchTreeFind(SearchTreeNode** root, SearchTreeType to_find); SearchTreeNode* _SearchTreeRemove(SearchTreeNode* root, SearchTreeType to_delete);

插入的實現

插入肯定會插入在葉子節點,
我們比較將要插入的節點和當前節點的大小關係,
如果大於當前節點,就需要在它的右子樹尋找合適的節點插入
如果小於當前節點,就要在它的左子樹尋找何時的節點插入

void SearchTreeInsert(SearchTreeNode** root, SearchTreeType key)
{
  if(root == NULL)
    return;
  if(*root == NULL)
  {
    SearchTreeInit(root,key);
  }
  //遞迴插入
  _SearchTreeInsert_R(*root,key);
}
SearchTreeNode* _SearchTreeInsert_R(SearchTreeNode* root, SearchTreeType key)
{
  if(root == NULL)
  {
    root = (SearchTreeNode*)malloc(sizeof(SearchTreeNode));
    root->key = key;
    root->rchild = NULL;
    root->rchild = NULL;
  }
  if(key > root->key)
  {
    root->rchild = _SearchTreeInsert_R(root->rchild,key);
  }
  else if(key < root->key)
  {
    root->lchild = _SearchTreeInsert_R(root->lchild,key);
  }
  else if( key == root->key )
  {
    return root;
  }
  return root;
}

查詢的實現

依然是一個比較的過程,查詢節點比當前節點大,就在當前節點的右子樹中繼續查詢
查詢節點比當前節點小,就在其左子樹進行查詢
如果遇到了NULL,就表示查詢失敗.
程式碼很簡單就不一一列舉了.

刪除的實現

刪除就比較複雜了,因為在刪除後還要保證這棵樹是一個二叉查詢樹.
這裡要分情況討論

刪除的是葉子節點

例如我們要刪除的是3 ,那麼我們就應該找到3的父節點5,將5的左子樹置空即可

刪除的節點的左子樹為空


例如我們要刪除的是3 ,那麼我們就應該找到3的父節點5,將5的左子樹指向 3的右子樹,然後釋放該節點

刪除的節點右子樹為空


同上一種情況,將找到3的父節點5,將5的左子樹指向 3的左子樹,然後釋放該節點

刪除節點左右子樹都非空


這裡我們有兩種可能的方案
1. 在3的左子樹中找到最大的節點(2.5) 將2.5和3調換位置,然後將置換後的3刪除

2. 在3的右子樹中找到最小節點(3.5),將2.5和3調換位置,然後將置換後的3刪除

我們只要按這4種情況不重不漏的分析下去,程式碼就很好寫了

SearchTreeNode* _SearchTreeRemove(SearchTreeNode* root, SearchTreeType to_delete)
{
  if(root == NULL)
    return NULL;
  if(root->key > to_delete)
  {
    root->lchild = _SearchTreeRemove(root->lchild,to_delete);  
  }
  if(root->key < to_delete)
  {
    root->rchild = _SearchTreeRemove(root->rchild,to_delete);
  }
  if(root->key == to_delete)
  {
    // root 是葉子節點
    if(root->lchild == NULL && root->rchild == NULL)
    {
      free(root);
      root = NULL;
      return NULL;
    }
    // root 非葉子節點 而且左子樹為空,和右子樹中最小元素交換,後刪除找到的節點
    else if(root->lchild == NULL && root->rchild != NULL)
    {
      SearchTreeNode* to_return = root->rchild;
      free(root);
      root = NULL;
      return to_return;
    }
    // root 非葉子節點,右子樹為空,和左子樹中最大元素交換,後刪除找到的節
    else if(root->rchild == NULL && root->lchild != NULL)
    {
      SearchTreeNode* to_return = root->lchild;
      free(root);
      root = NULL;
      return to_return;
    }
    // root 非葉子節點, 左子樹中最大值和右子樹中最大值 二選一交換 後刪除找到的節
    else if(root->lchild != NULL && root->rchild != NULL)
    {
      //採用賦值法
      //在左子樹取最大值
      SearchTreeNode* max = root->lchild;
      SearchTreeNode* max_parent = root->lchild; 
      while(max->rchild)
      {
        max_parent = max;
        max = max->rchild;
      }
      root->key = max->key;
      //左子樹是葉子節點(特殊情況)
      if(max_parent == max)
      {
        free(max);
        max = NULL;
        root->lchild = NULL;
      }
      else 
      {
        //不用判斷將左子樹的最大值至為空
        free(max_parent->rchild);
        max_parent->rchild = NULL;
      }
      return root;
    }
  }
  return root;
}

相關推薦

[C語言實現]實現查詢基本操作(,圖示)

定義 二叉查詢樹是一種特殊的二叉樹,它不僅是一顆二叉樹,還滿足如下性質 對於任何非葉子節點,他的左節點都小於它本身,而右節點都大於其本身. 它的左右子樹也分別而二叉搜尋樹 一般情況下,在這麼一棵樹中進行查詢,它的時間複雜度是 longnlon

自己實現一個查詢BinarySearchTree

需求 自己實現一個簡單的二叉查詢樹BinarySearchTree 二叉排序樹或者是一棵空樹,或者是具有下列性質的二叉樹: 若左子樹不空,則左子樹上所有結點的值均小於或等於它的根結點的值; 若右子樹不空,則右子樹上所有結點的值均大於或等於它的根結點的值;

C++資料結構 17 查詢

Bst(Binary Search Tree) 有以下性質: 每一個元素有一個鍵值,而且不予許重複 左子樹的鍵值都小於根節點的鍵值 右子樹的鍵值都大於根節點的鍵值 左右子樹都是二叉查詢樹 程式碼: #ifndef __BST_H__ #

C語言-基本操作以及搜尋基本操作

功能 二叉樹操作: 建立二叉樹 遍歷二叉樹(前序,中序,後續) 計算高度 計算結點數目 清空二叉樹 空樹判斷 二叉搜尋樹操作: 插入 最值(最大值,最小值) 刪除 程式碼 #include &l

C語言排序基本操作

定義: 二叉排序樹是一棵特殊的二叉樹。其必須滿足:要麼為空樹或者樹上任一結點,其值大於等於其左子樹上的任意結點值(左子樹非空),且小於其右子樹上任意結點的值(右子樹非空),其左右子樹也滿足該定義。 結

查詢查詢、插入、刪除、釋放等基本操作實現C語言

二叉查詢樹是一種特殊性質的二叉樹,該樹中的任何一個節點,它的左子樹(若存在)的元素值小於節點的元素值,右子樹(若存在)的元素值大於節點的元素值。 實現了二叉樹查詢樹的實現以及基本操作,包括查詢、插入、刪除、初始化、釋放等。 原始碼下載地址:http://download.c

資料結構之 查詢C語言實現

資料結構之 二叉查詢樹 1. 二叉查詢樹的定義 二叉查詢樹(binary search tree)是一棵二叉樹,或稱為二叉搜尋樹,可能為空;一棵非空的二叉查詢樹滿足一下特徵: 每個元素有一個關鍵字,並且任意兩個元素的關鍵字都不同;因此,所有的關鍵字都是唯

查詢C語言實現及其視覺化

0, 二叉搜尋樹的定義:(二叉查詢樹)(二叉排序樹)       (1)若左子樹非空,則左子樹上的所有的節點的值都小於根節點的值       (2)若右子樹非空,則右子樹上的所有的節點的值都大於根節點的值       (3)其左右子樹都是二叉搜尋樹             

C語言實現查詢(BST)的基本操作

     我們在上一篇部落格中講解了二叉樹,這一次我們來實現二叉樹的進階——二叉查詢樹(Binary Search Tree),又稱二插排序樹(Binary Sort Tree)。所以簡稱為BST。二插查詢樹的定義如下:1.若左子樹不為空,則左子樹上所有節點的值均小於它的根節

查詢的簡單實現C語言

老司機不多說,直接上程式碼 標頭檔案: #ifndef BINARYTREE_FIND_H_INCLUDED #define BINARYTREE_FIND_H_INCLUDED struct TreeNode; typedef struct Tr

C語言實現查詢的輸出

二叉樹是資料結構和演算法中的重要部分。本文將簡單介紹其中的一類——二叉查詢樹:         二叉排序樹(BinarySortTree),又稱二叉查詢樹、二叉搜尋樹。它或者是一棵空樹;或者是具有下列

詳解查詢演算法的實現c語言

 樹(Tree)是n(n≥0)個結點的有限集。在任意一棵非空樹中:(1)有且僅有一個特定的被稱為根(Root)的結點;(2)當n>1時,其餘結點可分為m(m>0)個互不相交的有限集T1,T2,…,Tm,其中每一個集合本身又是一棵樹,並且稱為根的子樹(SubTre

C++:查詢實現)——遍歷操作

     建立好二叉樹,有時候我們需要對整個二叉樹錦星遍歷,即輸出二叉樹的所有結點元素。理論上,遍歷的方式有無數種,順序可以自己任意選定,但是絕大部分遍歷方式在實際中並沒有用處,比較有用的的遍歷方式有兩種:廣度優先遍歷、深度優先遍歷。 (1)廣度優先遍歷        

資料結構——查詢的詳細實現(c++)

本文實現了二叉查詢樹的前序遍歷(遞迴與非遞迴)、中序遍歷(遞迴與非遞迴)、後序遍歷(遞迴與非遞迴)、插入過程、刪除過程、查詢過程等。 二叉樹的簡單介紹: 1、二叉樹中的每個節點都不能有多餘兩個的兒子。 2、二叉樹的深度要比N小得多。 假設每個節點被指

演算法練習之查詢 C++實現

/////////////////Tnode.h//////////////// class TNode { public: ////methods TNode(void); TNode(int data); ~TNode(void);

c語言實現連結串列)非後序遍歷

演算法思想 因為後序遍歷是先訪問左子樹,再訪問右子樹,最後訪問根節點。當用棧實現遍歷時,必須分清返回根節點時,是從左子樹返回的還是從右子樹返回的。所以使用輔助指標r指向最近已訪問的結點。當然也可以在節點中增加一個標誌域,記錄是否已被訪問。 #include<iost

C#實現查詢

/// <summary> /// 二叉樹節點的定義 /// </summary> public class Node { //本身的資料 public int dat

查詢 C++實現

二叉查詢樹的C++實現 二叉查詢樹(BST)是父節點的值比左兒子的值大,比右兒子的值小的一種二叉樹。其資料元素集合包括每個節點,每個節點又包含節點的值和它的左兒子和右兒子。基本操作有:構造空的BST;判空;查詢;插入;刪除和遍歷。可以採用遞迴的方法來定義這些操

C語言指標實現簡單排序

二叉排序樹排序規則: 左節點 <= 根節點 <= 右節點 樹節點: typedef struct _node { int data; struct _node *left