搜索算法总结

搜索算法总结

(红黑树没写。。)

 

参考资料:

《算法导论》

《算法: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("\n");
 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("\nQuick Sort:\n");
 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:\n");
 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!\n");
 87 }
 88 /*******************************************************************/
 89 
 90 
 91 /*******************************************************************/
 92 // 哨兵顺序查找
 93 void Sequential_Search2(int* nums, int length, int key)
 94 {
 95     printf("Sequential Search2:\n");
 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!\n");
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:\n");
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!\n");
150 }
151 /*******************************************************************/
152 
153 
154 /*******************************************************************/
155 // 插值查找
156 void Insert_Search(int* nums, int length, int key)
157 {
158     printf("Insert Search:\n");
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!\n");
182 }
183 /*******************************************************************/
184 
185 
186 /*******************************************************************/
187 // 斐波那契查找
188 void Fibonacci_Search(int* nums, int length, int key)
189 {
190     printf("Fibonacci Search:\n");
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:\n");
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!\n");
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!\n");
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:\n");
449     Bitree T = NULL;
450     for (int i = 0; i < length; ++i)
451     {
452         InsertBST(&T, nums[i]);
453     }
454     printf("PreOrder Traverse:\n");
455     PreOrderTraverse(T);
456     printf("\n");
457     printf("InOrder Traverse:\n");
458     InOrderTraverse(T);
459     printf("\n");
460     LevelTraverse(T);
461     printf("\n");
462 
463     start_time = clock();
464     printf("SearchBST %d:\n", key);
465     Bitree p;
466     int ret = SearchBST(T, key, NULL, &p);
467     if (ret == 1)
468         printf("Find!\n");
469     else
470         printf("Not Find!\n");
471     finish_time = clock();
472     duration = (double)(finish_time - start_time) / CLOCKS_PER_SEC * 1000;
473     printf( "%f ms\n\n", duration );
474 
475     printf("Delete %d:\n", nums[length/3*2]);
476     DeleteBST(&T, nums[length/3*2]);
477 
478     printf("PreOrder Traverse:\n");
479     PreOrderTraverse(T);
480     printf("\n");
481     printf("InOrder Traverse:\n");
482     InOrderTraverse(T);
483     printf("\n");
484     LevelTraverse(T);
485     printf("\n");
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:\n");
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!\n");
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!\n");
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:\n");
777     PreOrderTraverseAVL(T);
778     printf("\n");
779     printf("InOrder Traverse:\n");
780     InOrderTraverseAVL(T);
781     printf("\n");
782     LevelTraverseAVL(T);
783     printf("\n");
784 
785     start_time = clock();
786     printf("SearchAVL %d:\n", key);
787     AVLTree p;
788     int ret = SearchAVL(T, key, NULL, &p);
789     if (ret == 1)
790         printf("Find!\n");
791     else
792         printf("Not Find!\n");
793     finish_time = clock();
794     duration = (double)(finish_time - start_time) / CLOCKS_PER_SEC * 1000;
795     printf( "%f ms\n\n", 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!\n");
854             return 0;
855         }
856     }
857     printf("Find in %d\n", *addr);
858     return 1;
859 }
860 
861 void HashSearch(int* nums, int length, int key)
862 {
863     printf("Hash Search:\n");
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:\n");
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\n\n", key);
904 
905     printf("Static Search:\n\n");
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\n\n", 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\n\n", 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\n\n", 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\n\n", 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\n\n", duration );
935 
936     printf("Dynamic Search:\n\n");
937     printf("Binary Sort Tree:\n");
938     BinarySortTree(temp, length, key);                // 二叉排序树
939 
940     printf("AVL Tree:\n");
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\n\n", duration );
948 
949     return 0;
950 }

 

posted @ 2016-08-02 17:05  Juntaran  阅读(745)  评论(0编辑  收藏  举报