zoukankan      html  css  js  c++  java
  • 常用排序算法总结

    在面试或者数据结构相关的考试中,经常会被要求到的算法主要有插入排序、冒泡排序、归并排序和快速排序。对这几种算法,不但应该知道其原理或者过程,还应该对他们的各种特性了然于胸,从最好、最差、平均时间空间复杂度等方面对比其优劣。在面试中这几种排序算法也会经常作为手写代码能力的考量,所以应该要求自己对这几种算法的代码信手拈来。所以在此把几种算法详细记录一下。

    冒泡排序

    /***********冒泡排序************
    空间复杂度:O(1)
    时间复杂度:有序的时候最好情况为O(n),最坏和平均为O(n^2)
    稳定性:稳定
    */
    void bubbleSort(int *arr, int n){
    	for(int i = 1; i<n; i++){
    		int j = i-1;
    		while(j>=0){
    			if(arr[j] > arr[j+1]){
    				int tmp = arr[j];
    				arr[j] = arr[j+1];
    				arr[j+1] = tmp;
    				j--;
    			}
    			else break;//本趟遍历没有发生交换
    		}
    	}
    }
    

    快排

    //http://blog.csdn.net/morewindows/article/details/6684558 挖坑排序
    void quick_sort(int s[], int l, int r)  
    {  
        if (l < r)  
        {  
            
            int i = l, j = r, x = s[l];  
            while (i < j)  
            {  
                while(i < j && s[j] >= x) // 从右向左找第一个小于x的数  
                    j--;    
                if(i < j)   
                    s[i++] = s[j];  
                  
                while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数  
                    i++;    
                if(i < j)   
                    s[j--] = s[i];  
            }  
            s[i] = x;  
            quick_sort(s, l, i - 1); // 递归调用   
            quick_sort(s, i + 1, r);  
        }  
    }  
    

    插入排序

    /***********折半插入排序*************
    相对于直接插入排序,它在查找的时候用
    折半查找,减少了比较的次数,但是移动
    的次数不变,还是n平方
    空间复杂度:O(1)
    时间复杂度:O(n^2)
    稳定性:稳定
    ************************************/
    void insertSortBi(int *arr, int n){
    	int i, j, low, mid, high;
    	for(i = 2; i<=n; i++){
    		arr[0] = arr[i];//arr[0]为哨兵,不存放元素
    		low = 1; high = i-1;		
    		//折半查找,减少了比较次数
    		while(low <= high){
    			mid = (low+high)/2;
    			if(arr[mid] > arr[0]) high = mid-1;
    			else low = mid + 1;
    		}
    
    		//向后移动元素
    		for(j = i-1; j>=high+1; --j)
    			arr[j+1] = arr[j];
    		
    		arr[high+1] = arr[0];
    	}
    
    	//打印元素
    	//for(int k = 0; k<6; k++)
    		//cout<<arr[k]<<endl;
    }
    

    堆排序

    //从i节点开始调整,从0开始计数,len为节点总数
    void MinHeapFixdown(int a[], int i, int n)  
    {  
        int j, temp;  
      
        temp = a[i];  
        j = 2 * i + 1;  
        while (j < n)  
        {  
            if (j + 1 < n && a[j + 1] < a[j]) //在左右孩子中找最小的  
                j++;  
      
            if (a[j] >= temp)  
                break;  
      
            a[i] = a[j];     //把较小的子结点往上移动,替换它的父结点  
            i = j;  
            j = 2 * i + 1;  
        }  
        a[i] = temp;  
    } 
    
    //构建小根堆
    void buildMinHeap(int arr[], int len)
    {
    	for(int i = len/2-1; i>=0; i--)
    		//把第i个元素向下调整(如果大于子节点的话)
    		MinHeapFixdown(arr, i, len);
    }
    
    /***********堆排序*******
    堆排序需要先对线性表中的元素构建堆,然后根据堆的性质,
    输出堆顶元素,然后对输出堆顶后被破坏的堆重新调整为堆,
    如此重复,直到堆中仅剩下一个元素位置
    空间复杂度:O(1)
    时间复杂度:最好最坏和平均情况下都为O(nlogn)
    稳定性:不稳定
    */
    void heapSort(int arr[], int n)
    {
    	//构建小根堆,小根堆的排序后是从大到小的顺序
    	buildMinHeap(arr, n);
    	for(int i = n-1; i>0; i--){
    		swap(arr[i], arr[0]);
    		MinHeapFixdown(arr, 0, i);
    	}
    }
    
  • 相关阅读:
    MySQL手册
    字符串置换
    Java实现三角形计数
    Java实现求二叉树的路径和
    Excel催化剂开源第46波-按行列排列多个图形技术要点
    Excel催化剂开源第44波-窗体在Show模式下受Excel操作影响变为最小化解决方式
    Excel催化剂开源第45波-按原图大小导出图片
    个人永久性免费-Excel催化剂功能第105波-批量调整不规范的图形对象到单一单元格内存储
    Excel催化剂开源第42波-与金融大数据TuShare对接实现零门槛零代码获取数据
    Excel催化剂开源第43波-Excel选择对象Selection在.Net开发中的使用
  • 原文地址:https://www.cnblogs.com/mooba/p/6558032.html
Copyright © 2011-2022 走看看