• 搜索算法总结


    搜索算法总结

    (红黑树没写。。)

    参考资料:

    《算法导论》

    《算法:C语言实现(第1-4部分)》

    《大话数据结构》

    输出如下:

      1 #include <iostream>
      2 #include <bits/stdc++.h>
      3 
      4 #define MaxRandom 100                                // 随机数生成范围
      5 #define LengthOfWaitSort 20                            // 随机数生成个数
      6 
      7 using namespace std;
      8 
      9 
     10 /*******************************************************************/
     11 // 验证输出
     12 void printAfterSort(int* nums, int length)
     13 {
     14     for (int i = 0; i < length; ++i)
     15     {
     16         printf("%4d",nums[i]);
     17     }
     18     printf("
    ");
     19 }
     20 /*******************************************************************/
     21 
     22 
     23 /*******************************************************************/
     24 // 快速排序
     25 void quick_sort(int* nums, int left, int right)
     26 {
     27     if (left < right)
     28     {
     29         int i = left;
     30         int j = right;
     31         int flag = nums[left];
     32 
     33         while (i < j)
     34         {
     35             while (i<j && nums[j]>=flag)            // 从右向左找第一个比基数小的元素
     36             {
     37                 j --;
     38             }
     39             if (i < j)
     40             {
     41                 nums[i++] = nums[j];
     42             }
     43 
     44             while (i<j && nums[i]<=flag)            // 从左向右找第一个比基数大的元素
     45             {
     46                 i ++;
     47             }
     48             if (i < j)
     49             {
     50                 nums[j--] = nums[i];
     51             }
     52         }
     53 
     54         nums[i] = flag;
     55         quick_sort( nums, left, i-1 );
     56         quick_sort( nums, i+1, right);
     57     }
     58 }
     59 
     60 void QuickSort(int* nums, int length)
     61 {
     62     int left  = 0;
     63     int right = length - 1;
     64     quick_sort(nums, left, right);
     65     // 输出
     66     printf("
    Quick Sort:
    ");
     67     printAfterSort(nums, length);
     68 }
     69 /*******************************************************************/
     70 
     71 
     72 
     73 /*******************************************************************/
     74 // 顺序查找
     75 void Sequential_Search(int* nums, int length, int key)
     76 {
     77     printf("Sequential Search:
    ");
     78     for (int i = 0; i < length; ++i)
     79     {
     80         if (nums[i] == key)
     81         {
     82             printf("Find %d in nums[%d]", key, i);
     83             return;
     84         }
     85     }
     86     printf("Not Find!
    ");
     87 }
     88 /*******************************************************************/
     89 
     90 
     91 /*******************************************************************/
     92 // 哨兵顺序查找
     93 void Sequential_Search2(int* nums, int length, int key)
     94 {
     95     printf("Sequential Search2:
    ");
     96     if (nums[0] == key)
     97     {
     98         printf("Find %d in nums[0]", key);
     99         return;
    100     }
    101     int temp = nums[0];
    102     nums[0] = key;
    103     int i = length;
    104     while (nums[i] != key)
    105     {
    106         i --;
    107     }
    108     if (i == 0)
    109     {
    110         printf("Not Find!
    ");
    111         nums[0] = temp;
    112     }
    113     else
    114     {
    115         printf("Find %d in nums[%d]", key, i);
    116         nums[0] = temp;
    117         return;
    118     }
    119 }
    120 /*******************************************************************/
    121 
    122 
    123 /*******************************************************************/
    124 // 二分查找(有序)
    125 void Binary_Search(int* nums, int length, int key)
    126 {
    127     printf("Binary Search:
    ");
    128     int left, right, middle;
    129     left  = 0;
    130     right = length - 1;
    131 
    132     while (left <= right)
    133     {
    134         middle = (left + right) / 2;
    135         if (key < nums[middle])
    136         {
    137             right = middle - 1;
    138         }
    139         else if (key > nums[middle])
    140         {
    141             left = middle + 1;
    142         }
    143         else
    144         {
    145             printf("Find %d in nums[%d]", key, middle);
    146             return;
    147         }
    148     }
    149     printf("Not Find!
    ");
    150 }
    151 /*******************************************************************/
    152 
    153 
    154 /*******************************************************************/
    155 // 插值查找
    156 void Insert_Search(int* nums, int length, int key)
    157 {
    158     printf("Insert Search:
    ");
    159     int left, right, middle;
    160     left  = 0;
    161     right = length - 1;
    162 
    163     while (left <= right)
    164     {
    165         middle = left + (right-left)*(key-nums[left])/(nums[right]-nums[left]);
    166                                                     // 只在middle取值与二分不同
    167         if (key < nums[middle])
    168         {
    169             right = middle - 1;
    170         }
    171         else if (key > nums[middle])
    172         {
    173             left = middle + 1;
    174         }
    175         else
    176         {
    177             printf("Find %d in nums[%d]", key, middle);
    178             return;
    179         }
    180     }
    181     printf("Not Find!
    ");
    182 }
    183 /*******************************************************************/
    184 
    185 
    186 /*******************************************************************/
    187 // 斐波那契查找
    188 void Fibonacci_Search(int* nums, int length, int key)
    189 {
    190     printf("Fibonacci Search:
    ");
    191     int Fibonacci[1000];                            // 斐波那契数列
    192     Fibonacci[0] = 0;
    193     Fibonacci[1] = 1;
    194     for (int i = 2; i < 1000; ++i)
    195     {
    196         Fibonacci[i] = Fibonacci[i-1] + Fibonacci[i-2];
    197     }
    198     int left, right, middle;
    199     left  = 0;
    200     right = length - 1;
    201 
    202     int k = 0;
    203     while (length > Fibonacci[k]-1)                    // 计算n位于斐波那契数列的位置
    204     {
    205         ++k;
    206     }
    207     int* temp;                                        // 扩展nums到Fibonacci[k]-1的长度
    208     temp = new int [Fibonacci[k] - 1];
    209     memcpy(temp, nums, length* sizeof(int));
    210 
    211     for (int i = length; i < Fibonacci[k]-1; ++i)    // 填充剩余部分
    212     {
    213         temp[i] = nums[length - 1];
    214     }
    215 
    216     while (left <= right)
    217     {
    218         middle = left + Fibonacci[k-1] - 1;
    219         if (key < temp[middle])
    220         {
    221             right = middle - 1;
    222             k = k-1;                                // 斐波那契数列下标-1
    223         }
    224         else if (key > temp[middle])
    225         {
    226             left = middle + 1;
    227             k = k-2;                                // 斐波那契数列下标-2
    228         }
    229         else
    230         {
    231             if (middle < length)
    232             {
    233                 printf("Find %d in nums[%d]", key, middle);
    234                 return;
    235             }
    236             else
    237             {
    238                 printf("Find %d in nums[%d]", key, length-1);
    239                 return;
    240             }
    241         }
    242     }
    243     delete [] temp;
    244 }
    245 /*******************************************************************/
    246 
    247 
    248 /*******************************************************************/
    249 // 二叉排序树
    250 typedef struct BitNode                                // 结点结构
    251 {
    252     int data;
    253     struct BitNode *lchild;
    254     struct BitNode *rchild;
    255 } BitNode, *Bitree;
    256 
    257 int LevelTraverse(Bitree T)                            // 层序遍历
    258 {
    259     printf("Level Taverse:
    ");
    260     if (T == NULL)
    261     {
    262         return 0;
    263     }
    264     vector<BitNode *> vec;
    265     vec.push_back(T);
    266     int cur = 0;
    267     int last = 1;
    268 
    269     while (cur < vec.size())
    270     {
    271         last = vec.size();
    272         while (cur < last)
    273         {
    274             cout << vec[cur]->data << " ";
    275             if (vec[cur]->lchild != NULL)
    276             {
    277                 vec.push_back(vec[cur]->lchild);
    278             }
    279             if (vec[cur]->rchild != NULL)
    280             {
    281                 vec.push_back(vec[cur]->rchild);
    282             }
    283             ++ cur;
    284         }
    285         cout << endl;
    286     }
    287     return 0;
    288 }
    289 
    290 int PreOrderTraverse(Bitree T)                        // 前序遍历
    291 {
    292     if (T == NULL)
    293     {
    294 //        printf("Not Find!
    ");
    295         return 0;
    296     }
    297     printf("%4d ", T->data);
    298     PreOrderTraverse(T->lchild);
    299     PreOrderTraverse(T->rchild);
    300     return 0;
    301 }
    302 
    303 int InOrderTraverse(Bitree T)                        // 中序遍历
    304 {
    305     if (T == NULL)
    306     {
    307 //        printf("Not Find!
    ");
    308         return 0;
    309     }
    310     InOrderTraverse(T->lchild);
    311     printf("%4d ", T->data);
    312     InOrderTraverse(T->rchild);
    313     return 0;
    314 }
    315 
    316 /*
    317  * 递归查找二叉排序树T中是否存在key,
    318  * 指针f指向T的双亲,其初始调用值为NULL
    319  * 若查找成功,则指针p指向该数据元素结点,并返回1
    320  * 否则指针p指向查找路径上访问的最后一个结点并返回0
    321  */
    322 int SearchBST(Bitree T, int key, Bitree f, Bitree *p)
    323 {
    324     if (!T)                                            // 不存在
    325     {
    326         *p = f;
    327         return 0;
    328     }
    329     else if (key == T->data)                        // 查找成功
    330     {
    331         *p = T;
    332         return 1;
    333     }
    334     else if (key < T->data)
    335     {
    336         return SearchBST(T->lchild, key, T, p);        // 在左子树继续查找
    337     }
    338     else
    339     {
    340         return SearchBST(T->rchild, key, T, p);        // 在右子树继续查找
    341     }
    342 }
    343 
    344 /*
    345  * 二叉排序树中不存在key的时候,
    346  * 插入key返回1,否则返回0
    347  */
    348 int InsertBST(Bitree *T, int key)
    349 {
    350     Bitree p, s;
    351     if (!SearchBST(*T, key, NULL, &p))                // 没查到key
    352     {
    353         s = (Bitree)malloc(sizeof(BitNode));
    354         s->data = key;
    355         s->lchild = s->rchild = NULL;
    356         if (!p)
    357         {
    358             *T = s;                                    // 插入s为新的根结点
    359         }
    360         else if (key < p->data)
    361         {
    362             p->lchild = s;                            // 插入s为p的左孩子
    363         }
    364         else
    365         {
    366             p->rchild = s;                            // 插入s为p的右孩子
    367         }
    368         return 1;
    369     }
    370     else
    371         return 0;                                    // 原树中已有该节点
    372 }
    373 
    374 /*
    375  * 二叉排序树中删除p,
    376  * 重接它的左/右子树
    377  */
    378 int Delete(Bitree *p)
    379 {
    380     Bitree q, s;
    381     if ((*p)->rchild == NULL)                        // 右子树空则只需重接它的左子树(待删结点是叶子也走此分支)
    382     {
    383         q = *p;
    384         *p = (*p)->lchild;
    385         free(q);
    386     }
    387     else if ((*p)->lchild == NULL)                    // 只需重接它的右子树
    388     {
    389         q = *p;
    390         *p = (*p)->rchild;
    391         free(q);
    392     }
    393     else                                            // 左右子树均不为空
    394     {
    395         q = *p;
    396         s = (*p)->lchild;                            // 向左一步再向右走到头
    397         while (s->rchild)
    398         {
    399             q = s;
    400             s = s->rchild;
    401         }
    402         (*p)->data = s->data;                        // s指向被删结点的直接前驱(将被删结点前驱的值取代被删结点的值)
    403         if (q != *p)
    404         {
    405             q->rchild = s->lchild;                    // 重接q的右子树
    406         }
    407         else
    408         {
    409             q->lchild = s->lchild;                    // 重接q的左子树
    410         }
    411         free(s);
    412     }
    413     return 1;
    414 }
    415 
    416 /*
    417  * 若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素结点,
    418  * 否则返回0
    419  */
    420 int DeleteBST(Bitree *T, int key)
    421 {
    422     if (!*T)                                        // 不存在关键字等于key的数据元素
    423     {
    424         return 0;
    425     }
    426     else
    427     {
    428         if (key == (*T)->data)                        // 找到key
    429         {
    430             return Delete(T);
    431         }
    432         else if (key < (*T)->data)
    433         {
    434             return DeleteBST(&(*T)->lchild, key);
    435         }
    436         else
    437         {
    438             return DeleteBST(&(*T)->rchild, key);
    439         }
    440     }
    441 }
    442 
    443 void BinarySortTree(int* nums, int length, int key)
    444 {
    445     clock_t start_time, finish_time;
    446     double duration;
    447 
    448     printf("BinarySortTree:
    ");
    449     Bitree T = NULL;
    450     for (int i = 0; i < length; ++i)
    451     {
    452         InsertBST(&T, nums[i]);
    453     }
    454     printf("PreOrder Traverse:
    ");
    455     PreOrderTraverse(T);
    456     printf("
    ");
    457     printf("InOrder Traverse:
    ");
    458     InOrderTraverse(T);
    459     printf("
    ");
    460     LevelTraverse(T);
    461     printf("
    ");
    462 
    463     start_time = clock();
    464     printf("SearchBST %d:
    ", key);
    465     Bitree p;
    466     int ret = SearchBST(T, key, NULL, &p);
    467     if (ret == 1)
    468         printf("Find!
    ");
    469     else
    470         printf("Not Find!
    ");
    471     finish_time = clock();
    472     duration = (double)(finish_time - start_time) / CLOCKS_PER_SEC * 1000;
    473     printf( "%f ms
    
    ", duration );
    474 
    475     printf("Delete %d:
    ", nums[length/3*2]);
    476     DeleteBST(&T, nums[length/3*2]);
    477 
    478     printf("PreOrder Traverse:
    ");
    479     PreOrderTraverse(T);
    480     printf("
    ");
    481     printf("InOrder Traverse:
    ");
    482     InOrderTraverse(T);
    483     printf("
    ");
    484     LevelTraverse(T);
    485     printf("
    ");
    486 
    487     return;
    488 }
    489 /*******************************************************************/
    490 
    491 
    492 /*******************************************************************/
    493 // 平衡二叉树 AVL树
    494 typedef struct AVLNode                                // 节点结构
    495 {
    496     int data;
    497     int bf;                                            // 平衡因子
    498     struct AVLNode *lchild;
    499     struct AVLNode *rchild;
    500 } AVLNode, *AVLTree;
    501 
    502 int LevelTraverseAVL(AVLTree T)                        // 层序遍历
    503 {
    504     printf("Level Taverse:
    ");
    505     if (T == NULL)
    506     {
    507         return 0;
    508     }
    509     vector<AVLNode *> vec;
    510     vec.push_back(T);
    511     int cur = 0;
    512     int last = 1;
    513 
    514     while (cur < vec.size())
    515     {
    516         last = vec.size();
    517         while (cur < last)
    518         {
    519             cout << vec[cur]->data << " ";
    520             if (vec[cur]->lchild != NULL)
    521             {
    522                 vec.push_back(vec[cur]->lchild);
    523             }
    524             if (vec[cur]->rchild != NULL)
    525             {
    526                 vec.push_back(vec[cur]->rchild);
    527             }
    528             ++ cur;
    529         }
    530         cout << endl;
    531     }
    532     return 0;
    533 }
    534 
    535 int PreOrderTraverseAVL(AVLTree T)                    // 前序遍历
    536 {
    537     if (T == NULL)
    538     {
    539 //        printf("Not Find!
    ");
    540         return 0;
    541     }
    542     printf("%4d ", T->data);
    543     PreOrderTraverseAVL(T->lchild);
    544     PreOrderTraverseAVL(T->rchild);
    545     return 0;
    546 }
    547 
    548 int InOrderTraverseAVL(AVLTree T)                    // 中序遍历
    549 {
    550     if (T == NULL)
    551     {
    552 //        printf("Not Find!
    ");
    553         return 0;
    554     }
    555     InOrderTraverseAVL(T->lchild);
    556     printf("%4d ", T->data);
    557     InOrderTraverseAVL(T->rchild);
    558     return 0;
    559 }
    560 
    561 /*
    562  * 递归查找AVLTree T中是否存在key,
    563  * 指针f指向T的双亲,其初始调用值为NULL
    564  * 若查找成功,则指针p指向该数据元素结点,并返回1
    565  * 否则指针p指向查找路径上访问的最后一个结点并返回0
    566  */
    567 int SearchAVL(AVLTree T, int key, AVLTree f, AVLTree *p)
    568 {
    569     if (!T)                                            // 不存在
    570     {
    571         *p = f;
    572         return 0;
    573     }
    574     else if (key == T->data)                        // 查找成功
    575     {
    576         *p = T;
    577         return 1;
    578     }
    579     else if (key < T->data)
    580     {
    581         return SearchAVL(T->lchild, key, T, p);        // 在左子树继续查找
    582     }
    583     else
    584     {
    585         return SearchAVL(T->rchild, key, T, p);        // 在右子树继续查找
    586     }
    587 }
    588 
    589 
    590 /* 对以P为根的二叉排序树作右旋处理,
    591  * 处理之后P指向新的树根结点,
    592  * 即旋转处理之前的左子树的根结点
    593  */
    594 void R_Rotate(AVLTree *p)
    595 {
    596     AVLTree L;
    597     L = (*p)->lchild;                                // L指向P的左子树根结点
    598     (*p)->lchild = L->rchild;                        // L的右子树挂接为P的左子树
    599     L->rchild = (*p);
    600     *p = L;                                            // P指向新的根结点
    601 }
    602 
    603 /* 对以P为根的二叉排序树作左旋处理,
    604  * 处理之后P指向新的树根结点,
    605  * 即旋转处理之前的右子树的根结点
    606  */
    607 void L_Rotate(AVLTree *p)
    608 {
    609     AVLTree R;
    610     R = (*p)->rchild;                                // L指向P的右子树根结点
    611     (*p)->rchild = R->lchild;                        // L的右子树挂接为P的右子树
    612     R->lchild = (*p);
    613     *p = R;                                            // P指向新的根结点
    614 }
    615 
    616 #define LH +1                                         // 左高
    617 #define EH 0                                          // 等高
    618 #define RH -1                                         // 右高
    619 
    620 /*  对以指针T所指结点为根的二叉树作左平衡旋转处理
    621  *    本算法结束时,指针T指向新的根结点
    622  */
    623 void LeftBalance(AVLTree *T)
    624 {
    625     AVLTree L, Lr;
    626     L = (*T)->lchild;                                // L指向T的左子树根结点
    627     switch (L->bf)                                    // 检查T的左子树的平衡度,并作相应平衡处理
    628     {
    629         case LH:                                    // 新结点插入在T的左孩子的左子树上,要作单右旋处理
    630             (*T)->bf = L->bf = EH;
    631             R_Rotate(T);
    632             break;
    633         case RH:                                    // 新结点插入在T的左孩子的右子树上,要作双旋处理
    634             Lr = L->rchild;                            // Lr指向T的左孩子的右子树根
    635             switch (Lr->bf)                            // 修改T及其左孩子的平衡因子
    636             {
    637                 case LH:
    638                     (*T)->bf = RH;
    639                     L->bf = EH;
    640                     break;
    641                 case EH:
    642                     (*T)->bf = L->bf = EH;
    643                     break;
    644                 case RH:
    645                     (*T)->bf = EH;
    646                     L->bf = LH;
    647                     break;
    648             }
    649             Lr->bf = EH;
    650             L_Rotate(&(*T)->lchild);                // 对T的左子树作左旋平衡处理
    651             R_Rotate(T);                            // 对T作右旋平衡处理
    652     }
    653 }
    654 
    655 /*  对以指针T所指结点为根的二叉树作右平衡旋转处理
    656  *    本算法结束时,指针T指向新的根结点
    657  */
    658 void RightBalance(AVLTree *T)
    659 {
    660     AVLTree R, Rl;
    661     R = (*T)->rchild;                                // R指向T的右子树根结点
    662     switch (R->bf)                                    // 检查T的右子树的平衡度,并作相应平衡处理
    663     {
    664         case RH:                                    // 新结点插入在T的右孩子的右子树上,要作单左旋处理
    665             (*T)->bf = R->bf = EH;
    666             L_Rotate(T);
    667             break;
    668         case LH:                                    // 新结点插入在T的右孩子的左子树上,要作双旋处理
    669             Rl = R->lchild;                            // Rl指向T的右孩子的左子树根
    670             switch (Rl->bf)                            // 修改T及其右孩子的平衡因子
    671             {
    672                 case RH:
    673                     (*T)->bf = LH;
    674                     R->bf = EH;
    675                     break;
    676                 case EH:
    677                     (*T)->bf = R->bf = EH;
    678                     break;
    679                 case LH:
    680                     (*T)->bf = EH;
    681                     R->bf = RH;
    682                     break;
    683             }
    684             Rl->bf = EH;
    685             R_Rotate(&(*T)->rchild);                // 对T的右子树作右旋平衡处理
    686             L_Rotate(T);                            // 对T作左旋平衡处理
    687     }
    688 }
    689 
    690 /*  若在平衡的二叉排序树T中不存在和e有相同关键字的结点,则插入一个
    691  *     数据元素为e的新结点,并返回1,否则返回0。
    692  *     若因插入而使二叉排序树失去平衡,则作平衡旋转处理,
    693  *     布尔变量taller反映T长高与否。
    694  */
    695 int InsertAVL(AVLTree *T, int e, int* taller)
    696 {
    697     if (!*T)
    698     {
    699         *T = (AVLTree)malloc(sizeof(AVLNode));        // 插入新结点,树“长高”,置taller为1
    700         (*T)->data = e;
    701         (*T)->lchild = (*T)->rchild = NULL;
    702         (*T)->bf = EH;
    703         *taller = 1;
    704     }
    705     else
    706     {
    707         if (e == (*T)->data)                        // 树中已存在和e有相同关键字的结点则不再插入
    708         {
    709             *taller = 0;
    710             return 0;
    711         }
    712         if (e < (*T)->data)                            // 在T的左子树搜索
    713         {
    714             if (!InsertAVL(&(*T)->lchild, e, taller))
    715             {
    716                 return 0;
    717             }
    718             if (*taller)                            // 已插入到T的左子树中且左子树“长高”
    719             {
    720                 switch ((*T)->bf)                    // 检查T的平衡度
    721                 {
    722                     case LH:                        // 原本左子树比右子树高,需要作左平衡处理
    723                         LeftBalance(T);
    724                         *taller = 0;
    725                         break;
    726                     case EH:                        // 原本左、右子树等高,现因左子树增高而使树增高
    727                         (*T)->bf = LH;
    728                         *taller = 1;
    729                         break;
    730                     case RH:                        // 原本右子树比左子树高,现左、右子树等高
    731                         (*T)->bf = EH;
    732                         *taller = 0;
    733                         break;
    734                 }
    735             }
    736         }
    737         else                                        // 在T的右子树搜索
    738         {
    739             if (!InsertAVL(&(*T)->rchild, e, taller))
    740             {
    741                 return 0;
    742             }
    743             if (*taller)                            // 已插入到T的右子树中且右子树“长高”
    744             {
    745                 switch ((*T)->bf)                    // 检查T的平衡度
    746                 {
    747                     case LH:                        // 原本左子树比右子树高,现左、右子树等高
    748                         (*T)->bf = EH;
    749                         *taller = 0;
    750                         break;
    751                     case EH:                        // 原本左、右子树等高,现因右子树增高而使树增高
    752                         (*T)->bf = RH;
    753                         *taller = 1;
    754                         break;
    755                     case RH:                        // 原本右子树比左子树高,需要作右平衡处理
    756                         RightBalance(T);
    757                         *taller = 0;
    758                         break;
    759                 }
    760             }
    761         }
    762     }
    763     return 1;
    764 }
    765 
    766 void AVLTreeSort(int* nums, int length, int key)
    767 {
    768     clock_t start_time, finish_time;
    769     double duration;
    770     AVLTree T = NULL;
    771     int taller;
    772     for (int i = 0; i < length; ++i)
    773     {
    774         InsertAVL(&T, nums[i], &taller);
    775     }
    776     printf("PreOrder Traverse:
    ");
    777     PreOrderTraverseAVL(T);
    778     printf("
    ");
    779     printf("InOrder Traverse:
    ");
    780     InOrderTraverseAVL(T);
    781     printf("
    ");
    782     LevelTraverseAVL(T);
    783     printf("
    ");
    784 
    785     start_time = clock();
    786     printf("SearchAVL %d:
    ", key);
    787     AVLTree p;
    788     int ret = SearchAVL(T, key, NULL, &p);
    789     if (ret == 1)
    790         printf("Find!
    ");
    791     else
    792         printf("Not Find!
    ");
    793     finish_time = clock();
    794     duration = (double)(finish_time - start_time) / CLOCKS_PER_SEC * 1000;
    795     printf( "%f ms
    
    ", duration );
    796 
    797     return;
    798 }
    799 /*******************************************************************/
    800 
    801 
    802 /*******************************************************************/
    803 // 散列表
    804 #define NULLKEY -32768
    805 
    806 typedef struct
    807 {
    808     int *element;                                    // 数据元素存储基址,动态分配数组
    809     int count;                                        // 当前数据元素个数
    810 }  HashTable;
    811 
    812 int hashlength = 0;                                    // 散列表表长,全局变量
    813 
    814 // 初始化散列表
    815 int InitHashTable(HashTable *H)
    816 {
    817     hashlength = LengthOfWaitSort;
    818     H->count = hashlength;
    819     H->element = (int*)malloc(sizeof(int)*hashlength);
    820     for (int i = 0; i < hashlength; ++i)
    821     {
    822         H->element[i] = NULLKEY;
    823     }
    824     return 1;
    825 }
    826 
    827 // 散列函数
    828 int Hash(int key)
    829 {
    830     return key % hashlength;                        // 除留余数法
    831 }
    832 
    833 // 插入关键字进入散列表
    834 void InsertHash(HashTable *H, int key)
    835 {
    836     int addr = Hash(key);                            // 散列地址
    837     while (H->element[addr] != NULLKEY)                // 如果不为空,则冲突
    838     {
    839         addr = (addr+1) % hashlength;                // 开放定址法的线性探测
    840     }
    841     H->element[addr] = key;                            // 找到空位后插入
    842 }
    843 
    844 // 散列表查找
    845 int SearchHash(HashTable H, int key, int *addr)
    846 {
    847     *addr = Hash(key);                                // 求散列地址
    848     while (H.element[*addr] != key)                    // 冲突
    849     {
    850         *addr = (*addr + 1) % hashlength;            // 线性探测
    851         if (H.element[*addr] == NULLKEY || *addr == Hash(key))
    852         {
    853             printf("Not Find!
    ");
    854             return 0;
    855         }
    856     }
    857     printf("Find in %d
    ", *addr);
    858     return 1;
    859 }
    860 
    861 void HashSearch(int* nums, int length, int key)
    862 {
    863     printf("Hash Search:
    ");
    864     HashTable H;
    865     InitHashTable(&H);
    866     int p;
    867     for (int i = 0; i < length; ++i)
    868     {
    869         InsertHash(&H, nums[i]);
    870     }
    871     for (int j = 0; j < length; ++j)
    872     {
    873         key = nums[j];
    874         SearchHash(H, key, &p);
    875     }
    876     return;
    877 }
    878 /*******************************************************************/
    879 
    880 
    881 
    882 int main()
    883 {
    884     clock_t start_time, finish_time;
    885     double duration;
    886     srand( (unsigned)time(NULL) );                  // 生成随机数种子
    887     int length = LengthOfWaitSort;
    888     int nums[length];
    889     int temp[length];
    890 
    891     printf("Initial array:
    ");
    892     for (int i = 0; i < length; ++i)                // 输出随机数组nums
    893     {
    894         nums[i] = rand()%(MaxRandom-1);             // MaxRandom-1以内生成20个随机数
    895         printf("%4d", nums[i]);
    896     }
    897 
    898     memcpy(temp, nums, length*sizeof(int));         // temp为无序数组
    899 
    900     QuickSort(nums, length);                        // nums为有序数组
    901 //    int key = 100000;
    902     int key = nums[length / 3];
    903     printf("key is %d
    
    ", key);
    904 
    905     printf("Static Search:
    
    ");
    906     start_time = clock();
    907     Sequential_Search(nums, length, key);            // 顺序查找
    908     finish_time = clock();
    909     duration = (double)(finish_time - start_time) / CLOCKS_PER_SEC * 1000;
    910     printf( "%f ms
    
    ", duration );
    911 
    912     start_time = clock();
    913     Sequential_Search2(nums, length, key);            // 哨兵顺序查找
    914     finish_time = clock();
    915     duration = (double)(finish_time - start_time) / CLOCKS_PER_SEC * 1000;
    916     printf( "%f ms
    
    ", duration );
    917 
    918     start_time = clock();
    919     Binary_Search(nums, length, key);                // 二分查找
    920     finish_time = clock();
    921     duration = (double)(finish_time - start_time) / CLOCKS_PER_SEC * 1000;
    922     printf( "%f ms
    
    ", duration );
    923 
    924     start_time = clock();
    925     Insert_Search(nums, length, key);                // 插值查找
    926     finish_time = clock();
    927     duration = (double)(finish_time - start_time) / CLOCKS_PER_SEC * 1000;
    928     printf( "%f ms
    
    ", duration );
    929 
    930     start_time = clock();
    931     Fibonacci_Search(nums, length, key);            // 斐波那契查找
    932     finish_time = clock();
    933     duration = (double)(finish_time - start_time) / CLOCKS_PER_SEC * 1000;
    934     printf( "%f ms
    
    ", duration );
    935 
    936     printf("Dynamic Search:
    
    ");
    937     printf("Binary Sort Tree:
    ");
    938     BinarySortTree(temp, length, key);                // 二叉排序树
    939 
    940     printf("AVL Tree:
    ");
    941     AVLTreeSort(temp, length, key);                    // AVL二叉树
    942 
    943     start_time = clock();
    944     HashSearch(temp, length, key);                    // 散列表查找
    945     finish_time = clock();
    946     duration = (double)(finish_time - start_time) / CLOCKS_PER_SEC * 1000;
    947     printf( "%f ms
    
    ", duration );
    948 
    949     return 0;
    950 }
  • 相关阅读:
    vue组件详解(四)——使用slot分发内容
    vue组件详解(三)——组件通信
    vue组件详解(二)——使用props传递数据
    vue组件详解(一)——组件与复用
    vue表单详解——小白速会
    vue class与style 绑定详解——小白速会
    vue内置指令详解——小白速会
    vue计算属性详解——小白速会
    SQL查询当天、本周、本月记录详解
    SQL Server中使用convert进行日期转换
  • 原文地址:https://www.cnblogs.com/Juntaran/p/5729988.html
Copyright © 2020-2023  润新知