zoukankan      html  css  js  c++  java
  • 基础排序算法

    参考链接:http://blog.csdn.net/morewindows/article/category/859207

    快排-冒泡-直接插入-直接选择-归并-堆排序

    [swap]两数交换 不使用中间变量
    
    inline void swap( int &a , int & b) 
    { 
             if (a != b) /需判断 可能会置0
            { 
                     // a^b = c  对c用a可以解出b 对c用b 可以解出a
                     a = a ^ b;
                     //对c 用旧b解锁得到 a;
                     b = b ^ a;
                     //对c 用b(旧 a)解锁得到b;
                     a = a ^ b;
            } 
    
             if(a != b)
            {
                     //总数
                     a = a + b;
                     //总数- 旧b = 旧 a
                     b = a - b;
                     //总数- 新b(旧 a) = 旧b
                     a = a - b;
            }
    }  
    
    【快速排序】【挖坑填坑】
    算法思想:找到数组一个值(一般是第一个元素) 根据这个值把数组分成3堆,对这个堆进行递归
    21  5  19  1
    第一个数为准值
    右边找小的
    左边找大的
    1 5 19 1
    把准值扔到左右重叠的位置
    1  5  19  21
    准值 = 位置 = 3
    判断(left<准值)     
    递归(数组,0,准值-1);
    判断(准值>right)
    递归(数组,准值+1,right);
    
    void q_sort (int numbers[], int left, int right )
    {
             int pivot , l_hold, r_hold;
    
             l_hold = left ;
             r_hold = right ;
    
             //选取第一个元素作为阀值
             pivot = numbers [left];
    
             //以阀值为界限分组
             while (left < right)
            {
                     //右边找到一个比阀值小的循环结束
                     while ((numbers [right] >= pivot) && (left < right))
                             right--;
                     //假如找到把右边小的扔到左边去
                     if (left != right)
                    {
                             numbers[left ] = numbers[ right];
                             left++;
                    }
                     //左边找到一个比阀值大的循环结束
                     while ((numbers [left] <= pivot) && (left < right))
                             left++;
                     //假如找到把左边大的扔到右边去
                     if (left != right)
                    {
                             numbers[right ] = numbers[ left];
                             right--;
                    }
            }
            
             //把阀值放到left=right的地方
             numbers[left ] = pivot;
             //阀值记录为位置
             pivot = left ;
    
             //左右回到开始位置
             left = l_hold ;
             right = r_hold ;
    
             //左边到阀值前一个位置排序
             if (left < pivot)
                     q_sort(numbers , left, pivot-1);
             //阀值后一个位置到右边排序
             if (right > pivot)
                     q_sort(numbers , pivot+1, right);
    }
    
    
    【冒泡排序】
    
    算法思想:
    N个数字
    1.比较前后2个数字,大的往后面走,最大就是最后一个
    2.N=N-1,依此循环,N=0顺序就确定好了
    
    void _bsort (int * arr,int size)
    {
             //总共循环次数
             for(int i = 0; i < size ;i++)
                     //每次循环完确定一个最大然后缩小样本空间
                     for(int j = 1; j<size - i; j++)
                    {
                             if (arr [j - 1] > arr[j ]) 
                                     swap(arr [j - 1], arr[j ]); 
                    }
    }
    
    void _bsort_fast (int * arr,int size)
    {
             int flag = size;
             int k = 0;
             while(flag > 0)
            {
                     //flag为某个位置后全部有序的标志位
                     k = flag ;
                     //假如有序了退出循环
                     flag = 0;
                     for(int i= 1; i<k ; i++)
                    {
                             if(arr [i-1]> arr[i ])
                            {
                                     swap(arr [i-1], arr[i ]);
                                     flag = i ;
                            }
                    }
            }
    }
    
    【插入排序】
    
    算法思想:
    1.数组a[0,n-1],令i=0;
    2.a[0]有序,插入a[i],a[0..i]有序
    3.i++,直到i=n-1排序完成
    
    //小到大
    void _insert_sort (int * arr,int size)
    {
             int i ,j, k;
             for( i = 1;i < size;i ++)
            {
                     //为arr[i] 找位置
                     for( j = i-1; j >= 0; j --)
                    {
                             if(arr [i] > arr[j ])
                                     break;
                    }
                     //排除上面的循环没执行情况把下面语句加在 break上面也可以
                     //找到合适位置j插入 j后面的后移
                     if(j != i-1)
                    {
                             //保存arr[i]
                             int temp = arr[ i]; 
                             //从a[i] 后面一位开始将比 a[i]大的数据向后移
                             for( k = i-1; k > j ;k--)
                                     arr[k +1] = arr[ k];
                    
                             //将a[i] 放到正确位置上
                             arr[k + 1] = temp; 
                    }
            }
    }
    
    void insertsort2 (int a[], int n) 
    { 
             int i , j; 
             for (i = 1; i < n; i ++) 
            {
                     //a[i]与前一位相比如果遇到比 a[i]小的有序
                     //假如前面的比a[i]大进行移位插入
                     if (a [i] < a[i - 1]) 
                    { 
                             //记录a[i]
                             int temp = a[ i]; 
                             //条件语句是关键包括了搜索和移位
                             for (j = i - 1; j >= 0 && a [j] > temp; j --) 
                                     a[j + 1] = a[ j]; 
                             //a[i]插入
                             a[j + 1] = temp; 
                    } 
            }
    }  
    
    //可以遍历第i个数前面的数
    //可以比较第i个数和它前面的数
    //eg:if(a[i]>a[j])
    for(int i=1; i<n ; i++)
         for(int j= i-1; j >=0; j--)
    
    void Insertsort3 (int a[], int n) 
    { 
             int i , j; 
             for (i = 1; i < n; i ++) 
                     for (j = i - 1; j >= 0; j --) 
                    {       
                             //a[j]与前一位比较比它小就交换直到合适位置
                             if(a [j] > a[j +1])
                                     swap(a [j], a[j + 1]); 
                    }
    }  
    
    
    【直接选择排序】
    
    算法思想:与直接插入排序类似
    
    1.数组a[0,n-1],令i=0;
    2.a[0..i-1]有序,从无序区a[i,n-1]选择一个最小的,放到a[i]位置,使a[0,..i]有序
    3.i++,直到i=n-1排序完成
    
    void select_sort (int * arr, int size)
    {
             int i , j , mid_pos;
    
             for(i =0; i< size; i ++)
            {
                     mid_pos = i ;
                     //搜索i 位置后面的元素
                     //得到比a[i] 小的数的位置
                     for(j =i+1; j<size ; j++)
                    {
                             if(arr [mid_pos] > arr[j ])
                            {
                                     //记下最值得交换的位置
                                     mid_pos = j ;
                            }       
                    }
                             //和arr[i] 交换位置a[0..i]有序
                     swap(arr[mid_pos], arr[i ]);
                    
            }
    }
    
    【归并排序】
    
    算法思想:
    
    1.先递归分解数列,分到一个小组只有1个数据,有序
    2.再合并对称的2个数组完成归并
    
    void merge_array (int a[],int first, int mid , int last, int temp[])
    {
             int first_a = first, end_a = mid ;
             int first_b = mid + 1, end_b = last ;
             int k = 0;
    
             //比较两个小数组小的到新数组
             while(first_a <= end_a && first_b <= end_b )
            {
                     if(a [first_a]> a[first_b ])
                             temp[k ++] = a[ first_b++];
                     else
                             temp[k ++] = a[ first_a++];
            }
    
             //可能有剩余的补上
             while(first_a <= end_a)
                     temp[k ++] = a[ first_a++];
             //可能有剩余的补上
             while(first_b <= end_b)
                     temp[k ++] = a[ first_b++];
    
             //拷贝到a
             for(int i=0; i<k ; i++)
                     a[first + i] = temp[i ];
    }
    
    
    void merge_sort (int a[], int first, int last , int temp[]) 
    { 
             if(first < last)
            {
                     int mid = (first + last) / 2;
                     //右边有序
                     merge_sort(a ,first, mid,temp );
                     //左边有序
                     merge_sort(a ,mid+1, last,temp );
                     //合并两边
                     merge_array(a ,first, mid,last ,temp);
            }
    }  
    
    
    
    
    【堆排序】
    
    算法思想:
    1.建立堆
    2.排序
    
    
    //增加操作是儿子节点找父亲节点调整父亲节点往上走
    //删除操作时父亲节点(头节点 )找儿子节点调整儿子节点往下走
    
    void heap_min_add_fix (int * arr,int pos)
    {
    
             //i为新节点位置
             int i = pos;
             //j为父节点位置
             int j = (i-1)/2;
             int temp = arr[ i];
    
             while(j >=0)
            {
                     //假如父节点小不需要调整
                     if(arr [j] <= temp)
                             break;
    
                     //重新调整父节点、子节点位置
                     //父节点位置继续调整
                     arr[i ] = arr[ j];
                     i = j ;
                     j = (i -1)/2;
            }
             //新节点位置重新设置
             arr[i ] = temp;
    }
    
    void heap_min_add (int * arr,int pos, int data )
    {
             arr[pos ] = data;
             heap_min_add_fix(arr ,pos);
    }
    
    
    //堆的删除每次只能删除头结点
    void heap_min_delete_fix (int * arr,int pos , int nodesize )
    {
             //father
             int i = pos;
    
             int temp = arr[ i];
             //son node
             int j = 2*i+1;
    
             while(nodesize >j)
            {
                     //左右孩子找到最小的
                     if(j +1<nodesize && arr[j +1]<arr[ j])
                             j++;
    
                     if(temp =< arr[ j])
                             break;
    
                     //小的节点往上走
                     arr[i ] = arr[ j];
                     i = j ; //新父亲节点
                     j = 2*i +1 //新儿子节点
            }
            
             //找到这个父亲节点赋值
             arr[i ] = temp;
    }
    
    void heap_min_delete (int * arr,int size)
    {
             //最后一个节点与第一个节点交换
             //执行向下调整
             swap(arr [0],arr[ size-1]);
             heap_min_delete_fix(arr ,0,size-1);
    }
    
    void heap_create (int* arr, int size)
    {
             //拿到最后一个父节点父节点往下修复
             for(int i=( size-1)/2;i >=0;i--)
                     heap_min_delete_fix(arr ,i, size-1);
    }
    
    void heap_sort_min (int * arr, int size)
    {
             //每次拿a[n-1] 与a[0]交换
             //然后执行向下调整,调整 [0 -  n-2]
             //再执行a[n-2] 与a[0]交换
             //再往下执行调整,调整到 [0 - n-3]
             //每次将数据并入后面的有序区,完成后整个数组有序
             for(int i= size-1;i >=0; i++)
            {
                     swap(arr [0],arr[ i]);
                     heap_min_delete_fix(arr ,0,i);
            }
  • 相关阅读:
    taro 列表渲染
    taro 事件处理
    taro 项目、代码说明
    taro 开发注意点
    taro 知识点
    taro 学习资料
    egg 官方文档之:框架扩展(Application、Context、Request、Response、Helper的访问方式及扩展)
    node 学习资料
    node api 之:fs
    node api 之:stream
  • 原文地址:https://www.cnblogs.com/guyan/p/2661666.html
Copyright © 2011-2022 走看看