1. 程式人生 > >平衡查詢二叉樹

平衡查詢二叉樹

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


struct node {
int key;                        //資料域,key值 
int bf;                         // 平衡因子。
struct node *lchild,*rchild;    //樹的左右孩子
};


typedef struct node avltree;


#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))


#define handler_error(msg) \
{perror(msg);exit(EXIT_FAILURE);}




#define LL 1
#define RR 2
#define LR 3
#define RL 4


int insert_avltree(avltree **root,int key)
{
struct node *A,*B,*C,*p,*fp,*father_A;
int choice = 0;
//-----------------------------------------------------------------
//        建立要插入的節點。 
struct node *s = (struct node *)malloc(sizeof(struct node));
if (s == NULL) {
printf("file %s,line %d:malloc error\n",__FILE__,__LINE__);
return 1;
}
s->key = key;
s->lchild = s->rchild = NULL;
s->bf = 0;
//----------------------------------------------------------------
if (*root == NULL) {//如果樹的空樹則該節點作為根節點。
*root = s;
goto out1;
}
A = *root;            
p = *root;
fp = NULL;
father_A = NULL;
while (p != NULL) { //從根節點開始,走到要插入的節點的位置,也就是要遍歷“祖先節點”那條線。
if (p->bf != 0 ) {
A = p;//用A來記錄插入節點祖先節點中從下到上第一個可能出現失去平衡點的節點。
father_A = fp;//father_A用來記錄A節點的父節點。
}
fp = p;
if (key < p->key) 
p = p->lchild;
else
p = p->rchild;
}
//-------------------------------------------------------------
// 插入s節點到指定的位置。
        if (key < fp->key)
fp->lchild = s;
else
fp->rchild = s;
//--------------------------------------------------------------
//確定B節點,並修改A的平衡因子。
if (key < A->key) {
B = A->lchild;
A->bf = A->bf + 1;
} else {
B = A->rchild;
A->bf = A->bf - 1;
}
        //--------------------------------------------------------------
// 修改B至S路徑上個節點的平衡因子,原來的肯定都是0,思考下,為什麼? 結合A是怎麼選擇出來的。
         p = B;
while (p != s) {
if(key < p->key) {
p->bf = 1; p = p->lchild;
}else {
p->bf = -1; p = p->rchild;
}
}
//--------------------------------------------------------------
if (A->bf == 2 && B->bf == 1) // 3
choice = LL;
else if (A->bf == -2 && B->bf == -1) //-3
choice = RR;
else if (A->bf == 2 && B->bf == -1) //1
choice = LR;
else if (A->bf == -2 && B->bf == 1) // -1
choice = RL;
else  {
choice = 0;
}


//----------------------------------------------------------------
printf("choice = %d\n",choice);
switch (choice) {
case LL:
B = A->lchild;
A->lchild = B->rchild;
B->rchild = A;
A->bf = B->bf = 0;
if (father_A == NULL) *root = B;
else if (A == father_A->lchild) father_A->lchild = B;
elsefather_A->rchild = B;
break;
case LR:
B = A->lchild;
C = B->rchild;
B->rchild = C->lchild;
A->lchild = C->rchild;
C->lchild = B;
C->rchild = A;
if (s->key < C->key) {
A->bf = -1;B->bf = 0;C->bf = 0;
} else if (s->key > C->key) {
A->bf =0;B->bf = 1;C->bf = 0;
} else {
A->bf = 0;B->bf = 0;
}
if (father_A == NULL) *root = C;
else if (A == father_A->lchild) father_A->lchild = C;
else father_A->rchild = C;
break;
case RL:
B = A->rchild;
C = B->lchild;
B->lchild = C->rchild;
A->rchild = C->lchild;
C->lchild = A;
C->rchild = B;
if (s->key < C->key) {
A->bf = 0;B->bf = -1;C->bf = 0;
} else if (s->key > C->key) {
A->bf = 1;B->bf = 0;C->bf = 0;
} else {
A->bf = 0;B->bf = 0;
}
if (father_A == NULL) *root = C;
else if (A == father_A->lchild) father_A->lchild = C;
else father_A->rchild = C;
break;
case RR:
B = A->rchild;
A->rchild = B->lchild;
B->lchild = A;
A->bf = B->bf = 0;
if (father_A == NULL) *root = B;
else if (A == father_A->lchild) father_A->lchild = B;
else  father_A->rchild = B;
break;
default:
printf("the avl tree is OK when insert a node!\n");
break;
}


out1:
 return 0;
}


int create_avl(avltree **avl)
{
int a[] = {24,12,53,28,45,90};
int length = ARRAY_SIZE(a);
int i = 0;

*avl = NULL;


for (i=0;i<length;i++) {
insert_avltree(avl,a[i]);
printf("insert node %d\n",a[i]);
}

return 0;
}


struct node* search_avl(avltree *root,int key)
{
 while (root) {
  if (root->key == key) 
   return root;
  else if (key  < root->key)
   root = root->lchild;
 else 
   root = root->rchild;
 }


 return NULL;
}




int main(int argc,char *argv[])
{
avltree *root = NULL;
avltree *node = NULL;
int a[] = {10,20,29,24,12,53,45,90,100,290,28};
int length = ARRAY_SIZE(a);
int i = 0;


if (create_avl(&root)) {
printf("create bstree error!\n");
exit(1);
}


for (i=0;i<length;i++) {
node = search_avl(root,a[i]);
if (node == NULL) {
printf("%d you search is not exist in the tree!\n",a[i]);
}else {
printf("search successfully!,and the key is %d\n",node->key);
}
}


return 0;
}

相關推薦

平衡查詢

#include <stdio.h> #include <unistd.h> #include <malloc.h> #include <stdlib.h> struct node {int key;                        //資料域,k

騰訊2017暑假筆試題-查詢的根

/* 騰訊2017暑假筆試題-查詢二叉樹的根 對於一個高度為k的滿排序二叉樹,給定k和三個數, 找到這三個數的最小根節點 */ #include <iostream> #include <vector> #include <algorithm> u

LintCode(632)查詢中值最大的節點

問題 Find the maximum node in a binary tree, return the node. Example Given a binary tree: 1 / \ -5 2 / \ / \ 0 3 -4 -5

七大查詢演算法之查詢---查詢演算法

二叉樹查詢演算法        二叉查詢樹是先對待查詢的資料進行生成樹,確保樹的左分支的值小於右分支的值,然後在就行和每個節點的父節點比較大小,查詢最適合的範圍。 這個演算法的查詢效率很高,但是如果使用這種查詢方法要首先建立樹。 原理:         二叉查詢樹(Bi

C 查詢的基本操作

// // main.c // 二叉排序樹 // // Created by 赫凱 on 2018/10/31. // Copyright © 2018 赫凱. All rights reser

研究生畢業前一日三題:3,morris遍歷,及其平衡搜尋

tip:但凡要用遍歷處理的二叉樹問題,都可以用morris遍歷來解決。時間複雜度為N,空間複雜度為1                                                                                      

查詢 (一)

記錄分檔案寫模板類遇到的錯誤 1.將節點結構體的定義放在private中遇到的錯誤,錯誤程式碼如下: binarySearchTree.h #ifndef BINARYSEARCHTREE_H #

查詢(BST)

1、查詢二叉樹的定義 先上圖: 一棵二叉搜尋樹(Binary Sort Tree)是以一棵二叉樹來組織的,可以用連結串列資料結構來表示,其中,每一個結點就是一個物件,一般地,包含資料值和指向孩子(也可能是父母)的指標。如果某個孩子結點不存在,其指標為空(

資訊學奧賽一本通 查詢

查詢二叉樹 √ ”An easy problem“ 不過只要你不看錯題,基本上就沒事; 已知一棵二叉樹用鄰接表結構儲存, 中序查詢 二叉樹中值為x的結點,並指出是第幾個結點。例:如圖二叉樹的資料檔案的資料格式如下: 輸入:第一行n為二叉樹的結點個樹,n≤10

有序單向連結串列轉換為平衡搜尋

class BSTNode { public: BSTNode(int v) { value = v; left = NULL; right = NULL; } int value; BSTNode *left; BSTNode

查詢中符合特定條件的值

總結了一下基本用到的公式。 下面用陣列存了下,迴圈求解了 /* 滿二叉樹:一棵深度為h,且有2的(h)次方-1個節點的二叉樹 特點:每一層上的結點數都是最大結點數 它的葉子數是: 2^(h-1) 第k層的結點數是: 2^(h-1) 總結點數是: 2^h-1 (2的k次方減

資料結構-查詢

查詢二叉樹:始終滿足任一節點的左兒子小於該節點,右兒子大於該節點, 由於其特性,查詢二叉樹的中序遍歷始終為從小到大; 需要注意的是二叉查詢樹的刪除,有2種策略,在刪除節點不多時可以採用懶惰刪除,即標記該節點刪除而非真正的delete,第二種是當刪除節點只有一個兒子或則為葉子

給定陣列,如何快速建立查詢

二叉樹查詢一直以來是效率較高的查詢方式,現在我們從基礎開始,假如給定一個數組,如何根據陣列建立二叉樹 ? 轉載請註明出處: http://blog.csdn.net/elfprincexu 現附上

查詢的指定節點及根節點到該節點的路徑

//查詢二叉樹指定節點 bool hasNode(TreeNode* pRoot, TreeNode* pNode){ if(pRoot == pNode) return true; bool has = false; if(pRoot

查詢最大值節點

如題 : 在二叉樹中查詢最大值的節點並返回 測試資料 : {1,-5,3,1,2,-4,-5} 答案 : 3 思路 : 從根節點往下分別查詢左子樹和右子樹的最大節點,再比較左子樹,右子樹,根節點的大小

資料結構預算--二分法查詢--搜尋--平衡

資料結構預算--二叉搜尋樹與二分法查詢 二分法查詢 源於二分查詢的二叉樹搜尋 平衡二叉樹 二分法查詢 二分法:適用於從資料量較大,已經排序好的資料中定位目標資料節點的方法; 一般用於陣列中; 源於二分查詢的二叉樹搜尋 當資料量較

【學習筆記】平衡(AVL)簡介及其查詢、插入、建立操作的實現

  目錄 平衡二叉樹簡介: 各種操作實現程式碼:   詳細內容請參見《演算法筆記》P319 初始AVL樹,一知半解,目前不是很懂要如何應用,特記錄下重要內容,以供今後review。   平衡二叉樹簡介: 平衡二叉樹由兩位前

演算法導論 之 平衡 - 建立 插入 查詢 銷燬 - 遞迴 C語言

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

查詢-平衡

當用戶進行二叉排序樹的建立時,對於同一組資料,不同的插入次序的序列生成的不同形態的二叉排序樹。 而不同形態平均查詢長度一般是不同的,最壞形態的平均查詢長度是(n+1)/2,這顯然不是我們想要的情況,所以我們需要對二叉排序樹進行改進。  那麼怎樣提高二叉排序樹的查詢效率呢?

資料結構實驗之查詢平衡 (SDUT 3374)

#include <stdio.h> #include <string.h> #include <stdlib.h> struct node { int data; int h; struct node *lc,*rc; //平衡二