• 算法快速回顾——排序算法


    常用排序算法有以下几种:冒泡排序、插入排序、快速排序、归并排序、堆排序。

    本文将对五种常用算法分析并实现。

    //交换两个元素的值 这里列出几种不同写法
    void swap(int *a, int *b)
    {
        int c = *a;
        *a = *b;
        *b = c;
    }
    void swap(int *a,int *b)
    {
        *a = (*a)^(*b);
        *b = (*b)^(*a);
        *a = (*a)^(*b);
    }
    void swap(int *a,int *b)
    {
        *a = *a + *b;
        *b = *a - *b;
        *a = *a - *b;
    }
    
    
    //冒泡排序
    /*
    原理:比较相邻的两个元素,将小的往前调,大的元素向后调。对于相等的元素可以保持原来的次序,该算法是稳定的排序算法。由于算法将大的元素逐渐移动到后面,因而称为冒泡排序
    */
    void bubble_sort(int array[], int size)
    {
        int i,j,tmp;
        for(i =0; i<size;++i)
            for(j = size-1;j > i;--j)
                if(array[j]<array[j-1])
                    swap(&array[j],&array[j-1]);
    }
    
    
    //插入排序
    /*
    原理:构建有序数列,对于未排序的元素插入到有序数列中,最终所有元素排序完成。
    具体算法描述如下:
    1、从第一个元素开始,该元素可以认为已经被排序
    2、取出下一个元素,在已经排序的元素序列中从后向前扫描
    3、如果该元素(已排序)大于新元素,将该元素移到下一位置
    4、重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
    5、将新元素插入到该位置后
    6、重复步骤2~5
    */
    void insertion_sort(int array[], int first, int last)
    {
        int i,j,tmp;
        for(i = first+1;i<=last;i++)
        {
            j = i-1;//j前面的是排序好的有序数列
            tmp = array[i];
            while( j >= first && array[j]>tmp)
            {
                array[j+1] = array[j];
                j--;
            }
            array[j+1] = tmp;
        }
    }
    //快速排序算法
    /*
    原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列
    */
    void swap(int *a, int *b)
    {
        int c = *a;
        *a = *b;
        *b = c;
    }
    
    
    int Partition(int array[], int low, int high)
    {
        // 采用子序列的第一个元素为枢纽元素
        int pivot = array[low];
        while (low < high)
        {
            // 从后往前在后半部分中寻找第一个小于枢纽元素的元素
            while (low < high && array[high] >= pivot)
            {
                --high;
            }
            // 将这个比枢纽元素小的元素交换到前半部分
            array[low] =  array[high];
            // 从前往后在前半部分中寻找第一个大于枢纽元素的元素
            while (low < high && array[low] <= pivot)
            {
                ++low;
            }
            // 将这个比枢纽元素大的元素交换到后半部分
            array[high] =  array[low];
        }
        array[high]=pivot;    
    // 返回枢纽元素所在的位置     return low; } // 快速排序 void QuickSort(int array[], int low, int high) {     if (low < high)     {         int n = Partition(array, low, high);         QuickSort(array, low, n);         QuickSort(array, n + 1, high);     } } //归并排序 void merge(int[] unsorted, int first, int mid, int last, int[] sorted) { int i = first, j = mid; int k = 0; while (i < mid && j < last) if (unsorted[i] < unsorted[j]) sorted[k++] = unsorted[i++]; else sorted[k++] = unsorted[j++]; while (i < mid) sorted[k++] = unsorted[i++]; while (j < last) sorted[k++] = unsorted[j++]; for (int v = 0; v < k; v++) unsorted[first + v] = sorted[v]; } void merge_sort(int[] unsorted, int first, int last, int[] sorted) { if (first + 1 < last) { int mid = (first + last) / 2; Console.WriteLine("{0}-{1}-{2}", first, mid, last); merge_sort(unsorted, first, mid, sorted); merge_sort(unsorted, mid, last, sorted); merge(unsorted, first, mid, last, sorted); } }

     堆排序:摘自 http://blog.csdn.net/morewindows/article/details/6709644

     1 //插入i节点
     2 void MinHeapFixup(int a[], int i) 
     3 {
     4     int j,tmp;
     5     tmp = a[i];
     6     j = (i-1)/2;//父节点
     7     while(j >=0 && i !=0)
     8     {
     9         if(a[j] <=tmp)
    10             break;
    11         a[i]=a[j];
    12         i =j;
    13         j =(i-1)/2;
    14     }
    15     a[i] = tmp;
    16 }
    17 //调整节点
    18 //  从i节点开始调整,n为节点总数 从0开始计算 i节点的子节点为 2*i+1, 2*i+2  
    19 void MinHeapFixdown(int a[], int i, int n)  
    20 {
    21     int j, temp;  
    22   
    23     temp = a[i];  
    24     j = 2 * i + 1;  
    25     while (j < n)  
    26     {  
    27         if (j + 1 < n && a[j + 1] < a[j]) //在左右孩子中找最小的  
    28             j++;  
    29   
    30         if (a[j] >= temp)  
    31             break;  
    32   
    33         a[i] = a[j];     //把较小的子结点往上移动,替换它的父结点  
    34         i = j;  
    35         j = 2 * i + 1;  
    36     }  
    37     a[i] = temp;  
    38 }
    39 //删除节点
    40 
    41 //在最小堆中删除数  
    42 void MinHeapDeleteNumber(int a[], int n)  
    43 {  
    44     Swap(a[0], a[n - 1]);  
    45     MinHeapFixdown(a, 0, n - 1);  
    46 }  
    47 void MinheapsortTodescendarray(int a[], int n)  
    48 {  
    49     for (int i = n - 1; i >= 1; i--)  
    50     {  
    51         Swap(a[i], a[0]);  
    52         MinHeapFixdown(a, 0, i);  
    53     }  
    54 } 

    图片和部分代码部分摘自维基百科:http://zh.wikipedia.org/wiki/%E6%8F%92%E5%85%A5%E6%8E%92%E5%BA%8F

  • 相关阅读:
    c#线程带参数
    svn自动update到指定目录
    204. 计数质数
    178. 分数排名
    387. 字符串中的第一个唯一字符
    374. 猜数字大小
    371. 两整数之和
    350. 两个数组的交集 II
    326. 3的幂
    219. 存在重复元素 II
  • 原文地址:https://www.cnblogs.com/bigbigtree/p/3773621.html
Copyright © 2020-2023  润新知