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

目录

一、算法原理

顺序查找:

折半查找:

选择排序:

冒泡排序:

快速排序:

二、算法实现

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

选择排序的实现:

冒泡排序的实现:

快速排序的实现:

三、复杂度分析

顺序查找:

二分查找:

快速排序:

选择排序:

冒泡排序:


一、算法原理

  • 顺序查找:

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

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

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

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

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

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

  • //顺序查找和折半查找的源代码
    #include <iostream>
    using namespace std;
    //数据存储结构
    typedef struct {
    	int *elem;
    	int length;
    }Table; 
    //顺序查找算法 
    int Search(Table table , int key){
    	table.elem[0] = key;
    	int i;
    	for(i = table.length-1;table.elem[i] != key;--i);
    	return i;
    }
    
    //折半查找 
    int Binary_search(Table table,int key)
    {
    	int low=1,high=table.length,mid;
    	while(low<high){
    		mid = (low+high)/2;
    		if(table.elem[mid] == key){
    			return mid;
    		}else if(table.elem[mid]<key){
    			low = mid + 1;
    		}else{
    			high = mid-1;
    		}
    	}
    	return 0;
    }
    int main ()
    {
    	Table T ;
    	int a[10] = {0,1,2,3,4,5,6,7,8,9};   //0是为哨兵所留位置 (节省判断数组下标越界的代码的方法)
    	T.elem = a;
    	T.length = sizeof(a)/sizeof(int);
    	if(Search(T,5) == 0)
    	cout<<"查找失败!"<<endl;
    	else
    	cout<<Search(T,5)<<endl;
    	if(Binary_search(T,6) == 0 )
    	cout<<"查找失败!"<<endl;
    	else
    	cout<<Binary_search(T,6)<<endl;
    	return 0;
     }
    

    选择排序的实现:

  • #include<stdio.h>
    
    #define MAXNUM 100
    #define TRUE 1
    #define FALSE 0
    typedef int KeyType;
    typedef int DataType;
    
    typedef struct 
    {
        KeyType key;         /* 排序码字段 */
        /*DataType info;     记录的其它字段 */
    } RecordNode;
    
    typedef struct 
    {
        int n;               /* n为文件中的记录个数,n<MAXNUM */
        RecordNode record[MAXNUM];
    } SortObject;
    
    void  selectSort(SortObject * pvector) 
    {   /* 按递增序进行直接选择排序 */
        int i, j, k;
        RecordNode temp, *data = pvector->record;
    
        for( i = 0; i < pvector->n-1; i++ ) 
        {  /* 做n-1趟选择排序 */
            k = i;
            for (j = i+1; j < pvector->n; j++) /* 在无序区内找出排序码最小的记录Rk*/
                if (data[j].key < data[k].key) k = j;
            if (k != i) 
            {   /* 记录Rk与Ri互换 */
                temp = data[i];
                data[i] = data[k];
                data[k] = temp;
            }     
        }
    }
    
    SortObject vector={8, 49,38,65,97,76,13,27,49};
    
    int main()
    {
        int i;
        selectSort(&vector);
        for(i = 0; i < 8; i++)
          printf("%d ", vector.record[i]);
        getchar();
        return 0;
    }
    
    

    冒泡排序的实现:

  • #include<stdio.h>
    
    #define MAXNUM 100
    #define TRUE 1
    #define FALSE 0
    typedef int KeyType;
    typedef int DataType;
    
    typedef struct 
    {
        KeyType key;       /* 排序码字段 */
        /*DataType info;           记录的其它字段 */
    } RecordNode;
    
    typedef struct 
    {
        int n;               /* n为文件中的记录个数,n<MAXNUM */
        RecordNode record[MAXNUM];
    } SortObject;
    
    
    void  bubbleSort(SortObject * pvector) 
    {
        int i, j, noswap; 
        RecordNode temp, *data = pvector->record;
    
    for(i = 0; i < pvector->n-1; i++) 
    {         /* 做n-1次起泡 */
            noswap = TRUE;                          /* 置交换标志 */
            for (j = 0; j < pvector->n-i-1; j++)    /* 从前向后扫描 */
                if (data[j+1].key < data[j].key) 
    {  /* 交换记录 */
                    temp = data[j]; 
                    data[j] = data[j+1];
                    data[j+1] = temp;
                    noswap = FALSE;
                }
            if ( noswap ) break;    /* 本趟起泡未发生记录交换,算法结束 */
        }
    }
    
    SortObject vector={8, 49,38,65,97,76,13,27,49};
    
    int main()
    {
        int i;
        bubbleSort(&vector);
        for(i = 0; i < 8; i++)
            printf("%d ", vector.record[i]);
        getchar();
        return 0;
    }
    

    快速排序的实现:

  • #include<stdio.h>
    
    #define MAXNUM 100
    #define TRUE 1
    #define FALSE 0
    typedef int KeyType;
    typedef int DataType;
    
    typedef struct 
    {
        KeyType key;         /* 排序码字段 */
        /*DataType info;        记录的其它字段 */
    } RecordNode;
    
    typedef struct 
    {
        int n;               /* n为文件中的记录个数,n<MAXNUM */
        RecordNode record[MAXNUM];
    } SortObject;
    
    void quickSort(SortObject * pvector, int l, int r) 
    {
        int i, j;
        RecordNode temp, *data = pvector->record;
        
        if (l >= r) return;   /* 只有一个记录或无记录,则无须排序 */
    
        i = l;  j = r;  temp = data[i];
    
         while (i != j) 
        {   /* 寻找Rl的最终位置 */
            while( data[j].key >= temp.key && j > i )
                j--;         /* 从右向左扫描,查找第1个排序码小于temp.key的记录 */
            if (i < j) data[i++] = data[j];   
    
            while( data[i].key <= temp.key && j > i )
                i++;         /* 从左向右扫描,查找第1个排序码大于temp.key的记录 */
            if (i < j) data[j--] = data[i];
        }
    
        data[i] = temp;                 /* 找到Rl的最终位置 */
        quickSort(pvector, l, i-1);                 /* 递归处理左区间 */
        quickSort(pvector, i+1, r);            /* 递归处理右区间 */
    }
    
    SortObject vector = {8, 49,38,65,97,76,13,27,49};
    
    int main()
    {
        int i;
        quickSort(&vector, 0, 7);
        for(i = 0; i < 8; i++)
            printf("%d ", vector.record[i]);
        getchar();
        return 0;
    }
    

    三、复杂度分析

  • 顺序查找:

  • 最好的情况是数组的第 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)。

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值