当前位置:   article > 正文

查找算法和排序算法的实现(C语言)及复杂度分析_c语言查找与排序难点

c语言查找与排序难点

目录

一、算法原理

顺序查找:

折半查找:

选择排序:

冒泡排序:

快速排序:

二、算法实现

顺序查找和折半查找的实现

选择排序的实现:

冒泡排序的实现:

快速排序的实现:

三、复杂度分析

顺序查找:

二分查找:

快速排序:

选择排序:

冒泡排序:


一、算法原理

  • 顺序查找:

  •        就是从数组的第一个元素开始,依次比较,直到找到目标数据或查找失败。
  • 折半查找

  •        首先计算表中间的位置,将表中间位置处的关键字与查找的关键字进行比较,如果相等,则查找成功;否则利用中间位置将表分为前、后两个子表,如果中间位置的关键字大于查找的关键字,则查找前子表,否则查找后子表。重复上面的过程,直到找到要查找的关键字为止,否则查找失败不存在此关键字。
  • 选择排序

  •         从头至尾扫描序列,找出最小的一个元素,和第一个元素交换,接着从剩下的元素中继续这种选择和交换方式,最终得到一个有序序列。
  • 冒泡排序:

  •         相邻的元素两两比较,较大的数下沉,较小的数冒起来,这样一趟比较下来,最大(小)值就会排列在一端。
  • 快速排序:

  •         每趟排序时选出一个基准值,然后将所有元素与该基准值比较,并按大小分成左右两堆,然后递归执行该过程,直到所有元素都完成排序。
  • 二、算法实现

  • 顺序查找和折半查找的实现

    1. //顺序查找和折半查找的源代码
    2. #include <iostream>
    3. using namespace std;
    4. //数据存储结构
    5. typedef struct {
    6. int *elem;
    7. int length;
    8. }Table;
    9. //顺序查找算法
    10. int Search(Table table , int key){
    11. table.elem[0] = key;
    12. int i;
    13. for(i = table.length-1;table.elem[i] != key;--i);
    14. return i;
    15. }
    16. //折半查找
    17. int Binary_search(Table table,int key)
    18. {
    19. int low=1,high=table.length,mid;
    20. while(low<high){
    21. mid = (low+high)/2;
    22. if(table.elem[mid] == key){
    23. return mid;
    24. }else if(table.elem[mid]<key){
    25. low = mid + 1;
    26. }else{
    27. high = mid-1;
    28. }
    29. }
    30. return 0;
    31. }
    32. int main ()
    33. {
    34. Table T ;
    35. int a[10] = {0,1,2,3,4,5,6,7,8,9}; //0是为哨兵所留位置 (节省判断数组下标越界的代码的方法)
    36. T.elem = a;
    37. T.length = sizeof(a)/sizeof(int);
    38. if(Search(T,5) == 0)
    39. cout<<"查找失败!"<<endl;
    40. else
    41. cout<<Search(T,5)<<endl;
    42. if(Binary_search(T,6) == 0 )
    43. cout<<"查找失败!"<<endl;
    44. else
    45. cout<<Binary_search(T,6)<<endl;
    46. return 0;
    47. }

    选择排序的实现:

    1. #include<stdio.h>
    2. #define MAXNUM 100
    3. #define TRUE 1
    4. #define FALSE 0
    5. typedef int KeyType;
    6. typedef int DataType;
    7. typedef struct
    8. {
    9. KeyType key; /* 排序码字段 */
    10. /*DataType info; 记录的其它字段 */
    11. } RecordNode;
    12. typedef struct
    13. {
    14. int n; /* n为文件中的记录个数,n<MAXNUM */
    15. RecordNode record[MAXNUM];
    16. } SortObject;
    17. void selectSort(SortObject * pvector)
    18. { /* 按递增序进行直接选择排序 */
    19. int i, j, k;
    20. RecordNode temp, *data = pvector->record;
    21. for( i = 0; i < pvector->n-1; i++ )
    22. { /* 做n-1趟选择排序 */
    23. k = i;
    24. for (j = i+1; j < pvector->n; j++) /* 在无序区内找出排序码最小的记录Rk*/
    25. if (data[j].key < data[k].key) k = j;
    26. if (k != i)
    27. { /* 记录Rk与Ri互换 */
    28. temp = data[i];
    29. data[i] = data[k];
    30. data[k] = temp;
    31. }
    32. }
    33. }
    34. SortObject vector={8, 49,38,65,97,76,13,27,49};
    35. int main()
    36. {
    37. int i;
    38. selectSort(&vector);
    39. for(i = 0; i < 8; i++)
    40. printf("%d ", vector.record[i]);
    41. getchar();
    42. return 0;
    43. }

    冒泡排序的实现:

    1. #include<stdio.h>
    2. #define MAXNUM 100
    3. #define TRUE 1
    4. #define FALSE 0
    5. typedef int KeyType;
    6. typedef int DataType;
    7. typedef struct
    8. {
    9. KeyType key; /* 排序码字段 */
    10. /*DataType info; 记录的其它字段 */
    11. } RecordNode;
    12. typedef struct
    13. {
    14. int n; /* n为文件中的记录个数,n<MAXNUM */
    15. RecordNode record[MAXNUM];
    16. } SortObject;
    17. void bubbleSort(SortObject * pvector)
    18. {
    19. int i, j, noswap;
    20. RecordNode temp, *data = pvector->record;
    21. for(i = 0; i < pvector->n-1; i++)
    22. { /* 做n-1次起泡 */
    23. noswap = TRUE; /* 置交换标志 */
    24. for (j = 0; j < pvector->n-i-1; j++) /* 从前向后扫描 */
    25. if (data[j+1].key < data[j].key)
    26. { /* 交换记录 */
    27. temp = data[j];
    28. data[j] = data[j+1];
    29. data[j+1] = temp;
    30. noswap = FALSE;
    31. }
    32. if ( noswap ) break; /* 本趟起泡未发生记录交换,算法结束 */
    33. }
    34. }
    35. SortObject vector={8, 49,38,65,97,76,13,27,49};
    36. int main()
    37. {
    38. int i;
    39. bubbleSort(&vector);
    40. for(i = 0; i < 8; i++)
    41. printf("%d ", vector.record[i]);
    42. getchar();
    43. return 0;
    44. }

    快速排序的实现:

    1. #include<stdio.h>
    2. #define MAXNUM 100
    3. #define TRUE 1
    4. #define FALSE 0
    5. typedef int KeyType;
    6. typedef int DataType;
    7. typedef struct
    8. {
    9. KeyType key; /* 排序码字段 */
    10. /*DataType info; 记录的其它字段 */
    11. } RecordNode;
    12. typedef struct
    13. {
    14. int n; /* n为文件中的记录个数,n<MAXNUM */
    15. RecordNode record[MAXNUM];
    16. } SortObject;
    17. void quickSort(SortObject * pvector, int l, int r)
    18. {
    19. int i, j;
    20. RecordNode temp, *data = pvector->record;
    21. if (l >= r) return; /* 只有一个记录或无记录,则无须排序 */
    22. i = l; j = r; temp = data[i];
    23. while (i != j)
    24. { /* 寻找Rl的最终位置 */
    25. while( data[j].key >= temp.key && j > i )
    26. j--; /* 从右向左扫描,查找第1个排序码小于temp.key的记录 */
    27. if (i < j) data[i++] = data[j];
    28. while( data[i].key <= temp.key && j > i )
    29. i++; /* 从左向右扫描,查找第1个排序码大于temp.key的记录 */
    30. if (i < j) data[j--] = data[i];
    31. }
    32. data[i] = temp; /* 找到Rl的最终位置 */
    33. quickSort(pvector, l, i-1); /* 递归处理左区间 */
    34. quickSort(pvector, i+1, r); /* 递归处理右区间 */
    35. }
    36. SortObject vector = {8, 49,38,65,97,76,13,27,49};
    37. int main()
    38. {
    39. int i;
    40. quickSort(&vector, 0, 7);
    41. for(i = 0; i < 8; i++)
    42. printf("%d ", vector.record[i]);
    43. getchar();
    44. return 0;
    45. }

    三、复杂度分析

  • 顺序查找:

  • 最好的情况是数组的第 1 个元素就是我们要找的元素,这样可以直接找到。此时时间复杂度为O(1),最坏的情况是到最后一个元素时才找到或者没有找到要找的元素,时间复杂度为O(n)。查找成功时的平均查找长度为:(假设每个数据元素的概率相等) ASL = 1/n(1+2+3+…+n) = (n+1)/2 ;当查找不成功时,需要n+1次比较,时间复杂度为O(n); 所以,顺序查找的时间复杂度为O(n)。

    顺序查找是对数列顺序的比较,没有额外的空间,所以空间复杂度为常数 O(1)。

  • 二分查找:

  •    最好的情况是只查找一次就能找到,但是在最坏和一般情况下比顺序查找好了很多。二分查找的平均查找长度 ASL 为log2(n+1)-1所以二分查找的时间复杂度为 O(log2n)。二分查找的空间复杂度为O(1)。

  • 快速排序:

  • 快速排序最优的情况就是每一次取到的元素都刚好平分整个数组,最优的情况下时间复杂度为:O( nlogn )。最差的情况就是每一次取到的元素就是数组中最小/最大的,这种情况其实就是冒泡排序了,最差的情况下时间复杂度为:O( n^2 )。快速排序的平均时间复杂度也是:O(nlogn)。

    最优(每一次都平分数组)的情况下空间复杂度为:O(logn);最差(退化为冒泡排序)的情况下空间复杂度为:O( n )。

  • 选择排序:

  •     直接选择排序关键字比较次数永远是比较n(n-1)/2次,记录移动最少0次,最多3(n-1)次。所以,直接选择排序的时间复杂度是O(n^2)。它的空间复杂度是O(1)。

  • 冒泡排序:

  •     冒泡排序最好是关键字有序,n个关键字比较n-1次,记录移动0次。最坏是完全逆序,关键字比较n(n-1)/2次,记录移动3n(n-1)/2次。所以,冒泡排序的时间复杂度为O(n^2)。因为只是用了2个循环变量以及1到2个标志和交换等的中间变量,这个与待排序的记录个数无关,所以空间复杂度是O(1)。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/807667
推荐阅读
相关标签
  

闽ICP备14008679号