成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

淺談基礎算法之AVL tree和splay tree(三)

開發 架構 算法
平衡二叉樹:上文我們只實現了單旋,但是實際中為了達到平衡很多是要做雙旋操作的。先來看一張雙旋后的一張圖,明顯右邊的圖查詢的時候會更便捷。

承接上文,我們繼續聊這個話題。

平衡二叉樹:AVL Tree(1962)

上文我們只實現了單旋,但是實際中為了達到平衡很多是要做雙旋操作的。

先來看一張雙旋后的一張圖,明顯右邊的圖查詢的時候會更便捷。

  整個過程

  下面我們就進行代碼實踐。

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3.  
  4. #define max(a,b)    (((a) > (b)) ? (a) : (b))  
  5.  
  6. typedef struct AvlNode{ 
  7.     int data; 
  8.     struct AvlNode *left_child, *right_child; 
  9. } AvlNode; 
  10.  
  11. AvlNode *root; 
  12.  
  13. /*    旋轉動作開始        */ 
  14. AvlNode *rotate_LL(AvlNode *parent){ 
  15.     AvlNode *child = parent->left_child; 
  16.     parent->left_child = child->right_child; 
  17.     child->right_child = parent; 
  18.     return child; 
  19.  
  20. AvlNode *rotate_RR(AvlNode *parent){ 
  21.     AvlNode *child = parent->right_child; 
  22.     parent->right_child = child->left_child; 
  23.     child->left_child = parent; 
  24.     return child; 
  25.  
  26. AvlNode *rotate_RL(AvlNode *parent){ 
  27.     AvlNode *child = parent->right_child; 
  28.     parent->right_child = rotate_LL(child); 
  29.     return rotate_RR(parent); 
  30.  
  31. AvlNode *rotate_LR(AvlNode *parent){ 
  32.     AvlNode *child = parent->left_child; 
  33.     parent->left_child = rotate_RR(child); 
  34.     return rotate_LL(parent); 
  35. /*    旋轉動作結束    */ 
  36.  
  37. int get_height(AvlNode *node){ 
  38.     int height = 0; 
  39.     if(node != NULL){ 
  40.         height = 1 + max(get_height(node->left_child), get_height(node->right_child)); 
  41.     } 
  42.     return height; 
  43.  
  44. int get_balance(AvlNode *node){ 
  45.     if(node == NULL) return 0; 
  46.     return get_height(node->left_child) - get_height(node->right_child); 
  47.  
  48. /*    平衡二叉樹    */ 
  49. AvlNode *balance_tree(AvlNode **node){ 
  50.     int height_diff = get_balance(*node); /* 平衡因子在-1到1之間*/ 
  51.  
  52.     if(height_diff > 1){ 
  53.         if(get_balance((*node)->left_child) > 0){ 
  54.             *node = rotate_LL(*node); 
  55.         }else
  56.             *node = rotate_LR(*node); 
  57.         } 
  58.     }else if(height_diff < -1){ 
  59.         if(get_balance((*node)->right_child) < 0){ 
  60.             *node = rotate_RR(*node); 
  61.         }else
  62.             *node = rotate_RL(*node); 
  63.         } 
  64.     } 
  65.     return *node; 
  66.  
  67. AvlNode *avl_add(AvlNode **root, int key){ 
  68.     if(*root == NULL){ 
  69.         *root = (AvlNode *)malloc(sizeof(AvlNode)); 
  70.         if(*root == NULL){ 
  71.             printf("內存分配失敗!\n"); 
  72.             exit(-1); 
  73.         } 
  74.  
  75.         (*root)->data = key; 
  76.         (*root)->left_child = (*root)->right_child = NULL; 
  77.     }else if(key < (*root)->data){ 
  78.         (*root)->left_child = avl_add(&((*root)->left_child), key); 
  79.         //balance_tree(root); 
  80.     }else if(key > (*root)->data){ 
  81.         (*root)->right_child = avl_add(&((*root)->right_child), key); 
  82.         //balance_tree(root); 
  83.     }else
  84.         printf("復制%d失敗!\n", key); 
  85.         exit(-1); 
  86.     } 
  87.  
  88.     return *root; 
  89.  
  90. AvlNode *avl_print(AvlNode *node){ 
  91.     if(node == NULL) return NULL; 
  92.  
  93.     printf("%d->", node->data); 
  94.  
  95.     avl_print(node->left_child); 
  96.     avl_print(node->right_child); 
  97.     return node; 
  98.  
  99. int main(){ 
  100.     avl_add(&root, 24); 
  101.     avl_add(&root, 17); 
  102.     avl_add(&root, 40); 
  103.     avl_add(&root, 8); 
  104.     avl_add(&root, 22); 
  105.     avl_add(&root, 18); 
  106.     avl_add(&root, 23); 
  107.  
  108.     printf("打印二叉樹\n"); 
  109.     avl_print(root); 
  110.     printf("\n"); 
  111.  
  112.     balance_tree(&root); 
  113.     printf("打印二叉樹\n"); 
  114.     avl_print(root); 
  115.     printf("\n"); 
  116.     return 0; 

 

                   

讓我們看看伸展樹!     

伸展樹(Splay Tree,1985)

伸展樹的基本原理:

   

 舉例

我抽取一部分lighttpd-1.4.31.tar.gz中的代碼,來講解 

想看具體的代碼實踐的,可以到如下位置觀看

我的代碼結構:

代碼部分

  1. /*~ splaytree.h~*/ 
  2. typedef struct tree_node{ 
  3.     struct tree_node *left, *right; 
  4.     int key;    /*  關鍵字  */ 
  5.     int size;   /*  結點數目    */ 
  6.     void *data; 
  7. } splay_tree; 
  8. /*我現在只寫這兩個方法*/ 
  9. splay_tree * splaytree_insert(splay_tree *t, int key, void *data); 
  10. splay_tree * splaytree_splay(splay_tree *t, int key); 
  11. #define node_size(x) (((x)==NULL) ? 0 : ((x)->size)) 

這個沒有必要多講,看注釋和方法名稱自然就知道干嗎的了!

  1. /* splaytree.c */ 
  2. #include "splaytree.h" 
  3. #include <stdio.h> 
  4. #include <stdlib.h> 
  5. #include <assert.h> 
  6. #define compare(i,j) ((i) - (j)) 
  7. splay_tree * splaytree_insert(splay_tree *t, int key, void *data){ 
  8.     splay_tree * new
  9.  
  10.     if (t != NULL) { 
  11.         t = splaytree_splay(t, key); 
  12.         if(compare(key, t->key) == 0){ /*   該結點已存在    */ 
  13.             return t; 
  14.         } 
  15.     } 
  16.     new = (splay_tree *) malloc (sizeof (splay_tree)); 
  17.     assert(new); 
  18.     if (t == NULL) { 
  19.         new->left = new->right = NULL; 
  20.     } else if (compare(key, t->key) < 0) { 
  21.         new->left = t->left; 
  22.         new->right = t; 
  23.         t->left = NULL; 
  24.         t->size = 1 + node_size(t->right); 
  25.     } else { 
  26.         new->right = t->right; 
  27.         new->left = t; 
  28.         t->right = NULL; 
  29.         t->size = 1 + node_size(t->left); 
  30.     } 
  31.     new->key = key; 
  32.     new->data = data; 
  33. new->size = 1 + node_size(new->left) + node_size(new->right); 
  34.     return new
  35. splay_tree * splaytree_splay(splay_tree *t, int key){ 
  36.     splay_tree N, *l, *r, *child; /*    臨時變量用于裝配*t使用  */ 
  37.     int cmp, l_size, r_size; 
  38.     if (t == NULL) return t; 
  39.     N.left = N.right = NULL; 
  40.     l = r = &N; 
  41.     l_size = r_size = 0; 
  42.     for (;;) { 
  43.         cmp = compare(key, t->key); 
  44.  
  45.         if (cmp < 0) { 
  46.             if(t->left == NULL) break
  47.             if (compare(key, t->left->key) < 0) { 
  48.                 child = t->left;                        /*  右旋    */ 
  49.                 t->left = child->right; 
  50.                 child->right = t; 
  51.                 t->size = 1 + node_size(t->left) + node_size(t->right); 
  52.                 t = child; 
  53.                 if(t->left == NULL) break
  54.             } 
  55.             r->left = t;                                /*  右鏈    */ 
  56.             r = t; 
  57.             t = t->left; 
  58.             r_size += 1 + node_size(r->right); 
  59.         } else if (cmp > 0) { 
  60.             if(t->right == NULL) break
  61.  
  62.             if (compare(key, t->right->key) > 0) { 
  63.                 child =  t->right; 
  64.                 t->right = child->left; 
  65.                 child->left = t; 
  66.                 t->size = 1 + node_size(t->left) + node_size(t->right); 
  67.                 t = child; 
  68.                 if(t->right == NULL) break
  69.             } 
  70.             l->right = t; 
  71.             l = t; 
  72.             t = t->right; 
  73.             l_size += 1 + node_size(l->left); 
  74.         } else { 
  75.             break
  76.         } 
  77.     } 
  78.     l_size += node_size(t->left); 
  79.     r_size += node_size(t->right); 
  80.     t->size = 1 + l_size + r_size; 
  81.  
  82.     l->right = r->left = NULL; 
  83.  
  84.     /*  校驗size數據    */ 
  85.     /*右孩子的左結點不計算在內*/ 
  86.     for(child = N.right; child != NULL; child = child->right){ 
  87.         child->size = l_size; 
  88.         l_size -= 1 + node_size(child->left); 
  89.     } 
  90.     for(child = N.left; child != NULL; child = child->left){ 
  91.         child->size = r_size; 
  92.  r_size -= 1 +node_size(child->right); 
  93.     } 
  94.     /*  裝配數據    */ 
  95.     l->right = t->left; 
  96.     r->left = t->right; 
  97.     t->left = N.right; 
  98.     t->right = N.left; 
  99.     return t; 

看到上面一坨代碼估計大家不知所云了?

我就針對性的講解一下。

>> 重點講講講核心算法splaytree_splay()方法吧!

這個if講通,那么另一個else if也好理解。

  1. if (cmp < 0) { 
  2.             if(t->left == NULL) break
  3.  
  4.             if (compare(key, t->left->key) < 0) { 
  5.                 child = t->left;                        /*  右旋    */ 
  6.                 t->left = child->right; 
  7.                 child->right = t; 
  8.                 t->size = 1 + node_size(t->left) + node_size(t->right); 
  9.                 t = child; 
  10.  
  11.                 if(t->left == NULL) break
  12.             } 
  13.             r->left = t;                                /*  右鏈    */ 
  14.             r = t; 
  15.             t = t->left; 
  16.             r_size += 1 + node_size(r->right); 
  17.         } 

這是一個右旋的過程。

  child = t->left

t->left = child->right; child->right = t;

 最后:t = child

這是一個右鏈的過程

 r->left = t;r=t;

 t = t->left

3>main.c

  1. #include <stdio.h> 
  2. #include "splaytree.h" 
  3. splay_tree * splaytree_print(splay_tree *t){ 
  4.     if(t != NULL){ 
  5.         printf("t->data:%d\t t->key:%d t->size:%d\n", *((int *)t->data), t->key, t->size); 
  6.         splaytree_print(t->left); 
  7.         splaytree_print(t->right); 
  8.     } 
  9. int main(){ 
  10.     splay_tree *root; 
  11.     root = NULL; 
  12.     int data1 = 1000; 
  13.     root = splaytree_insert(root, 20, &data1); 
  14.     int data2 = 200; 
  15.     root = splaytree_insert(root, 5, &data2); 
  16.     int data3 = 300; 
  17.     root = splaytree_insert(root, 3, &data3); 
  18.     int data4 = 100; 
  19.     root = splaytree_insert(root, 10, &data4); 
  20.     printf("打印結果*************\n"); 
  21.     splaytree_print(root); 
  22.  
  23.  
  24.     //這里應該有個數據查詢過程,但是我沒有寫。注意在調用的時候調用一下splay方法, 
  25.     //那么熱數據自然就跑到頂端了。 
  26.     printf("查詢方法中調用這個伸展函數之后,打印結果*************\n"); 
  27.     root = splaytree_splay(root, 3); 
  28.     splaytree_print(root); 
  29.     return 0; 

這里我沒有把查詢伸展樹的過程寫下來,只是強調一下,在查詢的過程中,只要調用這個核心方法,那么自然熱數據就跑到頂端了。

看一下過程

 

 

原文鏈接:http://www.cnblogs.com/baochuan/archive/2012/10/16/2716641.html 

【編輯推薦】

  1. 大型網站后臺構建實踐
  2. 圖片存儲架構學習:緩存,架構師的美麗小三
  3. 淺談大型網站的算法和架構(二)
  4. 淺談大型網站的算法和架構
  5. 企業應用架構模式之工作單元模式
責任編輯:張偉 來源: 川山甲的博客
相關推薦

2022-10-30 10:03:20

B+數據庫數據

2024-02-27 07:35:55

B-TreeB+TreeMySQL

2019-11-26 15:12:08

數據存儲B+樹

2022-06-01 12:04:02

項目Webpack

2017-07-18 16:25:31

機器學習算法決策樹

2022-09-26 07:56:53

AVL算法二叉樹

2009-09-09 17:08:27

LINQ Expres

2011-08-16 09:13:45

tree中文man

2023-10-10 11:02:00

LSM Tree數據庫

2009-09-09 17:02:05

LINQ Expres

2023-01-04 08:33:31

Linuxtree命令

2022-10-29 08:44:39

分布式數據庫存儲

2020-02-13 17:27:31

CAPPaxos 共識算法

2010-10-12 16:50:14

MySQL Hash索

2011-11-24 21:12:35

ibmdw

2023-12-29 08:37:59

2011-09-14 09:30:27

2011-07-12 17:26:02

PHPPython

2012-09-28 14:08:20

大型網站架構大型網站算法算法

2017-03-20 10:14:03

語音識別匹配算法模型
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产丝袜一区二区三区免费视频 | 亚洲精品乱码8久久久久久日本 | 99精品在线免费观看 | h视频免费在线观看 | 91精品国产91久久综合桃花 | 日韩av一区二区在线观看 | 色本道 | 欧美日韩国产精品一区二区 | 亚洲成人精品国产 | 91精品国产综合久久国产大片 | 精品亚洲一区二区 | 六月色婷 | jvid精品资源在线观看 | 久久久久国产精品 | 国产精品久久久久久吹潮 | 亚洲一区二区三区乱码aⅴ 四虎在线视频 | 欧美视频1 | 国产一区二区三区视频免费观看 | 一级免费毛片 | 精品自拍视频在线观看 | 午夜电影网 | 香蕉av免费 | 久久久91 | 国产精品日韩欧美一区二区三区 | 毛片av免费在线观看 | 精品久久香蕉国产线看观看亚洲 | 人人草天天草 | 久久免费福利 | 亚洲视频一区在线观看 | 国产欧美精品在线观看 | 国产精品性做久久久久久 | 国产精品久久久久久久久久久免费看 | 中文字幕亚洲区一区二 | 男人影音| 99精彩视频 | 国产精品高潮呻吟久久av黑人 | av免费网站在线观看 | 亚洲 中文 欧美 日韩 在线观看 | 亚洲国产情侣 | 国精产品一区二区三区 | 亚洲bt 欧美bt 日本bt |