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);
    	}
    }
    
  • 相关阅读:
    【leetcode】1630. Arithmetic Subarrays
    【leetcode】1629. Slowest Key
    【leetcode】1624. Largest Substring Between Two Equal Characters
    【leetcode】1620. Coordinate With Maximum Network Quality
    【leetcode】1619. Mean of Array After Removing Some Elements
    【leetcode】1609. Even Odd Tree
    【leetcode】1608. Special Array With X Elements Greater Than or Equal X
    【leetcode】1603. Design Parking System
    【leetcode】1598. Crawler Log Folder
    Java基础加强总结(三)——代理(Proxy)Java实现Ip代理池
  • 原文地址:https://www.cnblogs.com/mooba/p/6558032.html
Copyright © 2011-2022 走看看