• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            羅朝輝(飄飄白云)

            關(guān)注嵌入式操作系統(tǒng),移動平臺,圖形開發(fā)。-->加微博 ^_^

              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              85 隨筆 :: 0 文章 :: 169 評論 :: 0 Trackbacks
             

            樹算法之紅黑樹   

            羅朝輝(http://www.shnenglu.com/kesalin

            轉(zhuǎn)載請注明出處


            紅黑樹本質(zhì)是二叉查找樹的一種,它的性能高于普通的二叉查找樹,即使是在最壞的情況下也能保證時間復(fù)雜度為O(lgn)。紅黑樹在每個結(jié)點上增加一個存儲位表示結(jié)點的顏色(或紅或黑,故稱紅黑樹)。通過對任何一條從根到葉子的路徑上各個結(jié)點著色方式的限制,紅黑樹可以保證沒有一條路徑會比其他路徑長出兩倍,因而是接近平衡的。

            紅黑樹的每個結(jié)點至少包含五個域:color,key,left,right 和 parent(一般我們都會在結(jié)點中存儲額外的數(shù)據(jù) data,但前面的五個域是必不可少的),如果某個結(jié)點沒有子結(jié)點或者結(jié)節(jié)點,則將相應(yīng)的指針設(shè)置為空值(NIL,注意不是 NULL,NIL是一個特定的空結(jié)點對象,類似于Obj-C 中 Nil對象)。我們將這些 NIL 當(dāng)作葉子結(jié)點(在實際處理過程中,往往將最底層的孩子結(jié)點和根結(jié)點的父親都指向同一個 NIL 結(jié)點,以便于處理紅黑樹代碼中的邊界條件),而將其它結(jié)點當(dāng)作內(nèi)結(jié)點。

            滿足如下 5 個性質(zhì)的二叉樹就是一顆紅黑樹:
            一,每個結(jié)點只有一種顏色,或紅色或黑色;
            二,根結(jié)點是黑色的;
            三,每個葉結(jié)點是黑色的;
            四,如果一個結(jié)點是紅色的,那么它的兩個孩子結(jié)點必須是黑色的;
            五,對每個結(jié)點,從該結(jié)點到其子孫結(jié)點的所有路徑上包含相同數(shù)目 H 的黑色結(jié)點, H 即為該節(jié)點的高度。

            紅黑樹的實現(xiàn),linux 內(nèi)核中有現(xiàn)成實現(xiàn)算法,園子里也有不少同學(xué)(那誰 等)實現(xiàn)過。在這里我重復(fù)制造一下輪子,當(dāng)然我這里的實現(xiàn)與前面提到的有些不同,這里是按照《算法導(dǎo)論》上的算法描述實現(xiàn)的。具體算法過程,請參考《算法導(dǎo)論》中紅黑樹那一章。

            下面先來看頭文件中包含的數(shù)據(jù)結(jié)構(gòu),接口函數(shù):

            #ifndef __RED_BLACK_TREE_H__
            #define __RED_BLACK_TREE_H__

            enum RBColor{
                RB_Red,
                RB_Black,
            }
            ;

            struct RBNode 
            {
                RBColor color;
                
            int key;
                RBNode
            * leftChild;
                RBNode
            * rightChild;
                RBNode
            * parent;
            }
            ;

            typedef RBNode
            * RBTree;

            RBNode
            * RBTree_nil();

            // 最小關(guān)鍵字元素
            RBNode* RBTree_minimum(RBNode* node);

            // 最大關(guān)鍵字元素
            RBNode* RBTree_maximum(RBNode* node);

            // 中序遍歷中的前驅(qū)
            RBNode* RBTree_predecessor(RBNode* node);

            // 中序遍歷中的后繼
            RBNode* RBTree_successor(RBNode* node);

            void RBTree_insert(RBTree* tree, RBNode* node);

            RBNode
            * RBTree_delete(RBTree* tree, RBNode* node);

            RBNode
            * RBTree_search(const RBTree tree, int key);

            void RBTree_print(RBTree tree, int her = 1);

            #endif    // __RED_BLACK_TREE_H__

            下面來看具體實現(xiàn):

            #include "RedBlackTree.h"
            #include 
            <stdlib.h>
            #include 
            <stdio.h>
            #include 
            <assert.h>

            static RBNode RBNode_Nil = {RB_Black, 0000};

            RBNode
            * RBTree_nil()
            {
                
            return &RBNode_Nil;
            }


            void RBTree_print(RBTree tree, int her)
            {
                
            int i;
                RBNode
            * node = tree;

                assert(node);

                
            if (node != &RBNode_Nil) {
                    
            for (i = 0; i < her; i++{
                        printf(
            " ");
                    }

                    printf(
            "第 %d 層, %d(%c)\n",
                        her, node
            ->key, node->color == RB_Black ? 'B' : 'R');

                    
            if (node->leftChild != &RBNode_Nil) {
                        RBTree_print(node
            ->leftChild, her + 1);
                    }


                    
            if (node->rightChild != &RBNode_Nil) {
                        RBTree_print(node
            ->rightChild, her + 1);
                    }

                }

            }


            // 最小關(guān)鍵字元素
            RBNode* RBTree_minimum(RBNode* node)
            {
                assert(node);

                RBNode
            * temp = node;
                
            while (temp->leftChild != &RBNode_Nil) {
                    temp 
            = temp->leftChild;
                }


                
            return temp;
            }



            // 最大關(guān)鍵字元素
            RBNode* RBTree_maximum(RBNode* node)
            {
                assert(node);

                RBNode
            * temp = node;
                
            while (temp->rightChild != &RBNode_Nil) {
                    temp 
            = temp->rightChild;
                }


                
            return temp;
            }


            // 中序遍歷中的前驅(qū)
            RBNode* RBTree_predecessor(RBNode* node)
            {
                assert(node);

                RBNode
            * child = node->leftChild;

                
            // 沒有左孩子,返回自身
                if (child == &RBNode_Nil) {
                    
            return node;
                }


                
            // 只有左孩子,則左孩子是其直接前驅(qū)
                else if (child->rightChild == &RBNode_Nil) {
                    
            return child->leftChild;
                }


                
            // 左右孩子均有,則右孩子樹中最大的元素為其直接前驅(qū)
                else {
                    
            return RBTree_maximum(child->rightChild);
                }

            }


            // 中序遍歷中的后繼
            RBNode* RBTree_successor(RBNode* node)
            {
                
            // 有右孩子,則右孩子樹中最小的元素為其直接后繼
                if (node->rightChild != &RBNode_Nil) {
                    
            return RBTree_minimum(node->rightChild);
                }


                
            // 沒有右孩子,向上找到的第一個左分支節(jié)點為其直接后繼,
                
            // 即 node 為其直接后繼的左孩子樹中的最大元素。
                RBNode* temp = node;
                RBNode
            * parent = temp->parent;

                
            while (parent != &RBNode_Nil && temp == parent->rightChild) {
                    temp 
            = parent;
                    parent 
            = temp->parent;
                }


                
            return parent;
            }


            RBNode
            * RBTree_search(const RBTree tree, int key)
            {
                RBNode
            * node = tree;

                
            while (node != &RBNode_Nil) {
                    
            if (node->key == key) {
                        
            return node;
                    }


                    
            else if (node->key < key) {
                        node 
            = node->rightChild;
                    }

                    
            else {
                        node 
            = node->leftChild;
                    }

                }


                
            return &RBNode_Nil;
            }


            // 左旋
            //            node                        right
            //           /    \                      /     \
            //          a    right     -->         node     c
            //              /     \               /    \
            //             b       c             a      b
            //
            void RBTree_left_rotate(RBTree* tree, RBNode* node)
            {
                assert(node
            ->rightChild && (*tree)->parent == &RBNode_Nil);

                RBNode
            * right = node->rightChild;

                
            // set b
                node->rightChild = right->leftChild;
                
            if (right->leftChild != &RBNode_Nil) {
                    right
            ->leftChild->parent = node;
                }


                right
            ->parent = node->parent;
                
            if (node->parent == &RBNode_Nil) {
                    
            *tree = right;
                }

                
            else if (node->parent->leftChild == node) {
                    node
            ->parent->leftChild = right;
                }

                
            else {
                    node
            ->parent->rightChild = right;
                }


                right
            ->leftChild = node;
                node
            ->parent = right;
            }


            // 右旋
            //            node                  left
            //           /    \                /    \
            //         left    c     -->      a     node
            //        /     \                      /    \
            //       a       b                    b      c
            //
            void RBTree_right_rotate(RBTree* tree, RBNode* node)
            {
                assert(node
            ->leftChild && (*tree)->parent == &RBNode_Nil);

                RBNode
            * left = node->leftChild;

                
            // set b
                node->leftChild = left->rightChild;
                
            if (left->rightChild != &RBNode_Nil) {
                    left
            ->rightChild->parent = node;
                }


                left
            ->parent = node->parent;
                
            if (node->parent == &RBNode_Nil) {
                    
            *tree = left;
                }

                
            else if (node->parent->leftChild == node) {
                    node
            ->parent->leftChild = left;
                }

                
            else {
                    node
            ->parent->rightChild = left;
                }


                left
            ->rightChild = node;
                node
            ->parent = left;
            }


            // 插入調(diào)整
            void RBTree_insert_fixup(RBTree* tree, RBNode* node)
            {
                assert(tree 
            && node);

                RBNode
            * parent = NULL;
                RBNode
            * uncle = NULL;
                RBNode
            * grand = NULL;
                RBNode
            * temp = NULL;

                parent 
            = node->parent;
                
            while (parent->color == RB_Red) {
                    
            // 根據(jù)紅黑樹性質(zhì),以及 node 的父親的顏色為紅色,
                    
            // 可以肯定 node 的祖父節(jié)點一定存在
                    grand = parent->parent;

                    
            // 確定叔父節(jié)點
                    if (parent == grand->leftChild) {
                        uncle 
            = grand->rightChild;

                        
            // case 1: 叔父節(jié)點為紅色
                        
            //         grand(B)        new node  ->    grand(R)
                        
            //         /     \                         /      \
                        
            //   parent(R)    uncle(R)    -->     node(B)   uncle(B)
                        
            //   /     \      /  \                /   \        /  \
                         
            //  a    node(R) d    e          parent  node(R)  d    e
                        
            //       /   \                          /   \
                        
            //      b     c                        b     c
                        
            //
                        if (uncle->color == RB_Red) {
                            parent
            ->color = RB_Black;
                            uncle
            ->color = RB_Black;
                            grand
            ->color = RB_Red;
                            node 
            = grand;
                            parent 
            = node->parent;
                        }


                        
            // case 2, case 3:叔父節(jié)點為黑色
                        
            //         case 2     --->    case 3         -->  done
                        
            //                      parent is as new node
                        
            //         grand(B)          grand(B)            node(B)
                        
            //         /     \           /      \           /      \
                         
            //   parent(R)    d       node(R)   d      parent(R)  grand(R)
                        
            //   /     \               /     \           /  \      /   \
                        
            //  a    node(R)      parent(R)   c         a    b    c     d
                         
            //       /   \         /  \
                        
            //      b     c       a    b
                        
            //
                        else {
                            
            // 將 case 2 裝換成 case 3
                            if (parent->rightChild == node) {
                                RBTree_left_rotate(tree, parent);
                                temp 
            = parent;
                                parent 
            = node;
                                node 
            = temp;
                            }


                            
            // case 3
                            parent->color = RB_Black;
                            grand
            ->color = RB_Red;

                            RBTree_right_rotate(tree, grand);
                        }

                    }

                    
            else {
                        
            // 與上面的情況對稱
                        uncle = grand->leftChild;

                        
            if (uncle->color == RB_Red) {
                            parent
            ->color = RB_Black;
                            uncle
            ->color = RB_Black;
                            grand
            ->color = RB_Red;
                            node 
            = grand;
                            parent 
            = node->parent;
                        }


                        
            else {
                            
            // 將 case 2 裝換成 case 3
                            if (parent->leftChild == node) {
                                RBTree_right_rotate(tree, parent);
                                temp 
            = parent;
                                parent 
            = node;
                                node 
            = temp;
                            }


                            
            // case 3
                            parent->color = RB_Black;
                            grand
            ->color = RB_Red;

                            RBTree_left_rotate(tree, grand);
                        }

                    }

                }


                (
            *tree)->color = RB_Black;
            }


            // 將節(jié)點 node 插入樹 tree 內(nèi),然后將 node 著色為紅色,此時,樹可能不再
            // 滿足紅黑樹性質(zhì),因此調(diào)用 RBTree_insert_fixup 來對節(jié)點重新著色調(diào)整。
            void RBTree_insert(RBTree* tree, RBNode* node)
            {
                assert(tree 
            && node);

                RBNode
            * parent = &RBNode_Nil;
                RBNode
            * temp = *tree;

                
            // 像二叉樹一樣,在樹中查找適當(dāng)?shù)奈恢貌迦?/span>
                while (temp != &RBNode_Nil) {
                    parent 
            = temp;

                    
            if (node->key < temp->key) {
                        temp 
            = temp->leftChild;
                    }

                    
            else {
                        temp 
            = temp->rightChild;
                    }

                }


                node
            ->parent = parent;

                
            // 樹為空
                if (parent == &RBNode_Nil) {
                    
            *tree = node;
                }

                
            else if (node->key < parent->key) {
                    parent
            ->leftChild = node;
                }

                
            else {
                    parent
            ->rightChild = node;
                }


                
            // 為節(jié)點著色
                node->leftChild = &RBNode_Nil;
                node
            ->rightChild = &RBNode_Nil;
                node
            ->color = RB_Red;

                
            // 調(diào)整樹使之滿足紅黑樹性質(zhì)
                RBTree_insert_fixup(tree, node);
            }


            // 刪除調(diào)整
            void RBTree_delete_fixup(RBTree* tree, RBNode* node)
            {
                RBNode
            * brother = NULL;
                RBNode
            * parent = NULL;

                
            while (node != *tree && node->color == RB_Black) {
                    parent 
            = node->parent;

                    
            // 確定兄弟節(jié)點
                    if (node == parent->leftChild) {
                        brother 
            = parent->rightChild;

                        
            // case 1: 兄弟節(jié)點為紅色
                        if (brother->color == RB_Red) {
                            brother
            ->color = RB_Black;
                            parent
            ->color = RB_Red;

                            RBTree_left_rotate(tree, parent);

                            brother 
            = node->parent->rightChild;
                        }


                        
            // case 2: 兄弟節(jié)點的兩孩子均為黑色
                        if (brother->leftChild->color == RB_Black
                            
            && brother->rightChild->color == RB_Black) {
                                brother
            ->color = RB_Red;
                                node 
            = parent;
                        }


                        
            else {
                            
            // case 3: 兄弟節(jié)點的左孩子為紅色,右孩子為黑色
                            if (brother->rightChild->color == RB_Black) {
                                brother
            ->leftChild->color = RB_Black;
                                brother
            ->color = RB_Red;

                                RBTree_right_rotate(tree, brother);

                                brother 
            = node->parent->rightChild;
                            }


                            
            // case 4:兄弟節(jié)點的右孩子為紅色
                            brother->color = parent->color;
                            parent
            ->color = RB_Black;
                            brother
            ->rightChild->color = RB_Black;

                            RBTree_left_rotate(tree, parent);

                            node 
            = *tree;
                        }

                    }

                    
            else {
                        brother 
            = node->parent->leftChild;

                        
            // case 1: 兄弟節(jié)點為紅色
                        if (brother->color == RB_Red) {
                            brother
            ->color = RB_Black;
                            parent
            ->color = RB_Red;

                            RBTree_right_rotate(tree, parent);

                            brother 
            = node->parent->leftChild;
                        }


                        
            // case 2: 兄弟節(jié)點的兩孩子均為黑色
                        if (brother->leftChild->color == RB_Black
                            
            && brother->rightChild->color == RB_Black) {
                                brother
            ->color = RB_Red;
                                node 
            = parent;
                        }


                        
            else {
                            
            // case 3: 兄弟節(jié)點的左孩子為紅色,右孩子為黑色
                            if (brother->rightChild->color == RB_Black) {
                                brother
            ->leftChild->color = RB_Black;
                                brother
            ->color = RB_Red;

                                RBTree_left_rotate(tree, brother);

                                brother 
            = node->parent->rightChild;
                            }


                            
            // case 4:兄弟節(jié)點的右孩子為紅色
                            brother->color = parent->color;
                            parent
            ->color = RB_Black;
                            brother
            ->leftChild->color = RB_Black;

                            RBTree_right_rotate(tree, parent);

                            node 
            = *tree;
                        }

                    }

                }


                node
            ->color = RB_Black;
            }


            // 刪除
            RBNode* RBTree_delete(RBTree* tree, RBNode* node)
            {
                RBNode
            * successor = NULL;
                RBNode
            * temp = NULL;

                
            if (node->leftChild == &RBNode_Nil || node->rightChild == &RBNode_Nil) {
                    successor 
            = node;
                }

                
            else {
                    successor 
            = RBTree_successor(node);
                }


                
            if (successor->leftChild != &RBNode_Nil) {
                    temp 
            = successor->leftChild;
                }

                
            else {
                    temp 
            = successor->rightChild;
                }


                temp
            ->parent = successor->parent;

                
            if (successor->parent == &RBNode_Nil) {
                    
            *tree = temp;
                }

                
            else {
                    
            if (successor == successor->parent->leftChild) {
                        successor
            ->parent->leftChild = temp;
                    }

                    
            else {
                        successor
            ->parent->rightChild = temp;
                    }

                }


                
            if (successor != node) {
                    node
            ->key = successor->key;
                }


                
            if (successor->color == RB_Black) {
                    RBTree_delete_fixup(tree, temp);
                }


                
            return successor;
            }

            測試代碼,測試數(shù)組中的數(shù)字與測試步驟是經(jīng)過仔細(xì)挑選的,以確保各個分支都可以測試到:

            void test_redblacktree_delete(RBTree* tree, int key)
            {
                RBNode
            * node = RBTree_search(*tree, key);
                assert(node 
            != RBTree_nil());

                printf(
            "\n刪除節(jié)點 %d \n", node->key);
                
                node 
            = RBTree_delete(tree, node);
                free(node);
                
                RBTree_print(
            *tree);
            }


            void test_redblacktree()
            {
                
            const int length = 14;
                
            int array[length] = {
                    
            2346711918121419172220
                }
            ;

                
            int i;
                RBTree tree 
            = RBTree_nil();
                RBNode
            * node = NULL;

                
            // 插入節(jié)點生成樹
                for (i = 0; i < length; i++{
                    node 
            = (RBNode*)malloc(sizeof(RBNode));
                    node
            ->key = array[i];
                    node
            ->color = RB_Red;
                    node
            ->parent = RBTree_nil();
                    node
            ->leftChild = RBTree_nil();
                    node
            ->rightChild = RBTree_nil();

                    RBTree_insert(
            &tree, node);    
                }


                RBTree_print(tree);

                
            // 插入測試
                node = (RBNode*)malloc(sizeof(RBNode));
                node
            ->key = 21;

                printf(
            "\n插入節(jié)點 %d\n", node->key);

                RBTree_insert(
            &tree, node);
                RBTree_print(tree);

                
            // 查找測試
                i = 6;
                node 
            = RBTree_search(tree, i);

                
            if (node != RBTree_nil()) {
                    printf(
            "\n在紅黑樹中找到節(jié)點 %d\n", node->key);
                }

                
            else {
                    printf(
            "\n在紅黑樹中找不到節(jié)點 %d\n", i);
                }


                
            // 刪除測試
                
            // 
                i = 4;// 取值 1, 2, 3, 4,分別對應(yīng) case 1, 2, 3, 4

                
            switch (i)
                
            {
                
            case 1:    // 兄弟為紅色
                    test_redblacktree_delete(&tree, 3);
                    
            break;

                
            case 2:    // 兄弟為黑色,且兄弟的兩孩子均為黑色
                    test_redblacktree_delete(&tree, 12);
                    
            break;

                
            case 3:    // 兄弟為黑色,且兄弟的左孩子為紅色,右孩子均為黑色
                    test_redblacktree_delete(&tree, 19);
                    
            break;

                
            case 4:    // 兄弟為黑色,且兄弟的右孩子為紅色
                    test_redblacktree_delete(&tree, 9);
                    
            break;
                }


                test_redblacktree_delete(
            &tree, 21);

                
            // 刪除樹
                for (i = 0; i < length; i++{
                    node 
            = RBTree_search(tree, array[i]);

                    
            if (node != RBTree_nil()) {
                        printf(
            "刪除 %d\n", node->key);
                        node 
            = RBTree_delete(&tree, node);
                        free(node);
                    }

                }


                assert(tree 
            == RBTree_nil());
            }


            測試結(jié)果
            ===============================================
            創(chuàng)建紅黑樹
            -------------------------------
             第 1 層, 6(B)
              第 2 層, 3(B)
               第 3 層, 2(B)
               第 3 層, 4(B)
              第 2 層, 12(B)
               第 3 層, 9(R)
                第 4 層, 7(B)
                第 4 層, 11(B)
               第 3 層, 18(R)
                第 4 層, 14(B)
                 第 5 層, 17(R)
                第 4 層, 20(B)
                 第 5 層, 19(R)
                 第 5 層, 22(R)

            插入節(jié)點 21
            -------------------------------
             第 1 層, 6(B)
              第 2 層, 3(B)
               第 3 層, 2(B)
               第 3 層, 4(B)
              第 2 層, 12(R)
               第 3 層, 9(B)
                第 4 層, 7(B)
                第 4 層, 11(B)
               第 3 層, 18(B)
                第 4 層, 14(B)
                 第 5 層, 17(R)
                第 4 層, 20(R)
                 第 5 層, 19(B)
                 第 5 層, 22(B)
                  第 6 層, 21(R)

            在紅黑樹中找到節(jié)點 6
            -------------------------------

            刪除節(jié)點 9
            -------------------------------
             第 1 層, 6(B)
              第 2 層, 3(B)
               第 3 層, 2(B)
               第 3 層, 4(B)
              第 2 層, 18(R)
               第 3 層, 12(B)
                第 4 層, 11(B)
                 第 5 層, 7(R)
                第 4 層, 14(B)
                 第 5 層, 17(R)
               第 3 層, 20(B)
                第 4 層, 19(B)
                第 4 層, 22(B)
                 第 5 層, 21(R)

            刪除節(jié)點 21
            -------------------------------
             第 1 層, 6(B)
              第 2 層, 3(B)
               第 3 層, 2(B)
               第 3 層, 4(B)
              第 2 層, 18(R)
               第 3 層, 12(B)
                第 4 層, 11(B)
                 第 5 層, 7(R)
                第 4 層, 14(B)
                 第 5 層, 17(R)
               第 3 層, 20(B)
                第 4 層, 19(B)
                第 4 層, 22(B)

            刪除 2
            刪除 3
            刪除 4
            刪除 6
            刪除 7
            刪除 11
            刪除 18
            刪除 12
            刪除 14
            刪除 19
            刪除 17
            刪除 22
            刪除 20

            測試結(jié)束




            posted on 2011-04-03 11:21 羅朝輝 閱讀(1883) 評論(0)  編輯 收藏 引用 所屬分類: Algorithms
            一本色道久久88加勒比—综合| 欧美久久久久久精选9999| 久久久久久国产a免费观看不卡| 精品久久一区二区| 97久久综合精品久久久综合| 久久久久久午夜成人影院| 亚洲级αV无码毛片久久精品| 久久久久国产精品人妻| 色青青草原桃花久久综合| 久久亚洲国产精品成人AV秋霞| 亚洲午夜无码久久久久小说| 精品国产乱码久久久久软件| 99久久99久久精品国产片果冻 | 久久91精品国产91| 国产精品久久久久AV福利动漫 | 一本色道久久99一综合| 久久亚洲国产精品一区二区| 国产精品九九久久精品女同亚洲欧美日韩综合区 | 久久久久99这里有精品10| 久久99国产综合精品女同| 久久综合九色综合欧美就去吻| 久久国产精品99精品国产| 欧美久久久久久精选9999| 久久不射电影网| 一本久久a久久精品亚洲| 久久er国产精品免费观看8| 亚洲性久久久影院| 一本一道久久精品综合| 久久香蕉超碰97国产精品| 国产2021久久精品| 久久无码人妻一区二区三区午夜| 亚洲国产精品嫩草影院久久| 亚洲国产精品久久久久婷婷软件| 亚洲精品无码久久一线| 伊人久久大香线蕉无码麻豆| 国产综合成人久久大片91| 精品久久久久久无码专区不卡| 久久亚洲精品无码VA大香大香| 欧美激情精品久久久久久| 99久久精品这里只有精品| 久久精品国产福利国产秒|