zoukankan      html  css  js  c++  java
  • 几大排序算法

    转载请标明出处:http://i.cnblogs.com/EditPosts.aspx?postid=4711012&update=1

    1.直接插入排序

    思想:待排序记录R[1...n]看成两段,有序R[1...m],无序R[m+1,n],每次将无序记录插到有序记录中,直到整体有序。

    // InsertSort.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include<iostream>
    #include <vector>
    #include <iterator>
    
    using namespace std;
    
    void print(int a[],int n)
    {
        for (int i=0;i<n;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    
    void insert_sort(int a[],int n)
    {
        int i,j,temp;
        for (i=1;i<n;i++)
        {
            temp=a[i];
            for (j=i-1;j>=0&&temp<a[j];j--)
            {
                a[j+1]=a[j];
            }
            a[j+1]=temp;
        }
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
        int a[]= {7,3,5,8,9,1,2,4,6};
        cout<<"before :"<<endl;
        print(a,9);
        insert_sort(a,9);
        cout<<"after:"<<endl;
        print(a,9);
        system("pause");
        return 0;
    }
    插入排序

    2.shell排序

    思想:按增量d分组排序,d每次减半,直至1

    // shell_sort.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    
    void print(int a[],int n)
    {
        for (int i=0;i<n;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    
    void shell_sort(int a[],int n)
    {
        int d,i,j,temp;
        for (d=n/2;d>0;d=d/2)//增量控制
        {
            for(i=d;i<n;i++)//插入排序类似
            {
                temp=a[i];
                for (j=i-d;(j>=0&&a[j]>temp);j-=d)
                {
                    a[j+d]=a[j];
                }
                a[j+d] = temp;
            }
        }
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        int a[]= {7,3,5,8,9,1,2,4,6};
        cout<<"before :"<<endl;
        print(a,9);
        shell_sort(a,9);
        cout<<"after:"<<endl;
        print(a,9);
        system("pause");
        return 0;
    }
    shell

    看成改进后的插入排序

    3.冒泡排序

    思想:每两个一比较,n个元素比较n-1次,得到一个目标元素

    // bubble_sort.cpp : 定义控制台应用程序的入口点。
    
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    
    void print(int a[],int n)
    {
        for (int i=0;i<n;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    
    void bubble_sort(int a[],int n)
    {
        int i=0;
        int j=0;
        int temp=0;
        int exchange=0;
        for (i=0;i<n-1;i++)//n-1趟
        {
            for (j=0;j<n-i-1;j++)
            {
                if (a[j+1]<a[j])
                {
                    temp=a[j];
                    a[j]=a[j+1];
                    a[j+1]=temp;
                    exchange = 1;
                }
            }
            if (exchange!=1)//没有交换,进行下一次扫描
            {
                return;
            }
        }
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        int a[]= {7,3,5,8,9,1,2,4,6};
        cout<<"before :"<<endl;
        print(a,9);
        bubble_sort(a,9);
        cout<<"after:"<<endl;
        print(a,9);
        system("pause");
        return 0;
    }
    bubble_sort

    4.快速排序

    思想:选取第一个元素为基准,通过一趟排序将序列分为大小两部分,此时正好得到基准的正确位置。再以此对左右两部分递归划分

    从右找第一个小于pivot的元素,交换;再从左找第一个大于pivot的元素,交换。。。

    // bubble_sort.cpp : 定义控制台应用程序的入口点。
    
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    
    void print(int a[],int n)
    {
        for (int i=0;i<n;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    
    void quick_sort(int a[],int low,int high)
    {
        int i,j,pivot;
        if (low<high)
        {
            i=low;
            j=high;
            pivot=a[low];
            while(i<j)
            {
                while (i<j && a[j]>=pivot)--j;
                if(i<j)
                {
                    a[i]=a[j];
                    i++;
                }
                //a[i++]=a[j];
                while(i<j&&a[i]<pivot)++i;
                if (i<j)a[j--]=a[i];
            }
        
            a[i]=pivot;
            quick_sort(a,low,i-1);
            quick_sort(a,i+1,high);
        }
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        int a[]= {7,3,5,8,9,1,2,4,6};
        cout<<"before :"<<endl;
        print(a,9);
        quick_sort(a,0,8);
        cout<<"after:"<<endl;
        print(a,9);
        system("pause");
        return 0;
    }
    quick_sort
    // bubble_sort.cpp : 定义控制台应用程序的入口点。
    
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    
    void print(int a[],int n)
    {
        for (int i=0;i<n;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    
    int getMiddle(int a[],int low,int high)
    {
        int i=low;
        int j=high;
        int pivot=a[low];
        while(i<j)
        {
            while (i<j && a[j]>=pivot)--j;
            if(i<j)
            {
                a[i]=a[j];
                i++;
            }
            //a[i++]=a[j];
            while(i<j&&a[i]<pivot)++i;
            if (i<j)a[j--]=a[i];
        }
        return i;
    }
    void quick_sort(int a[],int low,int high)
    {
        if (low<high)
        {
            int middle=getMiddle(a,low,high);
            quick_sort(a,low,middle-1);
            quick_sort(a,middle+1,high);
        }
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        int a[]= {7,3,5,8,9,1,2,4,6};
        cout<<"before :"<<endl;
        print(a,9);
        quick_sort(a,0,8);
        cout<<"after:"<<endl;
        print(a,9);
        system("pause");
        return 0;
    }
    quick_sort2
    // quicksort.cpp : 定义控制台应用程序的入口点。
    /*
       以上给出的是最初的版本,该程序为算法导论给出的原址排序   
    */
    
    #include "stdafx.h"
    #include <iostream>
    
    using namespace std;
    
    void print(int a[],int size)
    {
        for (int i=0;i<size;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    
    void exchange(int &a,int &b)
    {
        int temp=a;
        a=b;
        b=temp;
    }
    
    int partition(int a[],int p,int r)
    {
        int x=a[r];
        int i=p-1;
        int j;
        for (j=p;j<=r-1;j++)
        {
            if(a[j]<x)
            {
                i++;
                exchange(a[j],a[i]);
            }
        }
        exchange(a[i+1],a[r]);
        return i;
    }
    
    void quicksort(int a[],int low,int high)
    {
        int pos;
        if (low<high)
        {
            pos=partition(a,low,high);
            quicksort(a,low,pos);
            quicksort(a,pos+1,high);
        }
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        int a[]={5,3,6,7,9,8,1,4,2};
        cout<<"before:"<<endl;
        print(a,9);
        quicksort(a,0,8);
        cout<<"after:"<<endl;
        print(a,9);
        system("pause");
        return 0;
    }
    PARTITION

    5.选择排序

    思想:在要排序的序列中选出最小的一个与第一个交换,然后在剩下的选出次小的与第二个交换,以此类推。

    // bubble_sort.cpp : 定义控制台应用程序的入口点。
    
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    
    void print(int a[],int n)
    {
        for (int i=0;i<n;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    
    void select_sort(int a[],int n)
    {
        int minValue,index;
        for (int i=0;i<n;i++)//n-1次遍历
        {
            minValue=a[i];
            index=i;
            for (int j=i;j<n;j++)
            {
                if (a[j]<minValue)//保存每次遍历的最小数和下标
                {
                    minValue=a[j];
                    index=j;
                }
            }
            a[index]=a[i];//把最小值和a[i]交换
            a[i]=minValue;
        }
    }
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        int a[]= {7,3,5,8,9,1,2,4,6};
        cout<<"before :"<<endl;
        print(a,9);
        select_sort(a,9);
        cout<<"after:"<<endl;
        print(a,9);
        system("pause");
        return 0;
    }
    select_sort

     6.堆排序

    思想:将R[1...n]看成是一棵完全二叉树的顺序存储结构,则:

    1).将原始序列建成大(小)根堆;

    2).将根与最后一个节点交换,输出根节点;

    3).将2得到的二叉树调整为大根堆;

    重复2),3);

    /// bubble_sort.cpp : 定义控制台应用程序的入口点。
    
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    
    int heapsize = 0;
    int Left(int index){return (index<<1)+1;} //2i+1
    int Right(int index){return (index<<1)+2;}//2i+2
    
    void swap(int *a,int *b)
    {
        int t;
        t = *a;
        *a= *b;
        *a= t;
    }
    
    void print(int a[],int n)
    {
        for (int i=0;i<n;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    
    void HeapAjustify(int a[],int index)
    {
        int left = Left(index);
        int right = Right(index);
        int largest=0;//记录最大值的下标
        if ((left<=heapsize)&&(a[left]<a[index]))largest=index;
        else largest=left;
        if ((right<=heapsize)&&(a[right]>a[largest]))largest = right;
        
        if (largest!=index)//index为根的子树中根最大不是根
        {
            swap(&a[largest],&a[index]);//
            HeapAjustify(a,largest);
        }
    }
    
    void buildMaxHeap(int a[],int arrLen)
    {
        heapsize = arrLen;
        for (int i=arrLen>>1;i>=0;i--)
        {
            HeapAjustify(a,i);
        }
    }
    void heap_sort(int a[],int aSize)
    {
        buildMaxHeap(a,aSize-1);//(1)建堆
        for (int i=aSize-1;i>=1;i--)
        {                       //for(0--size){
            swap(&a[0],&a[i]);  //(2)堆输出
            heapsize--;
            HeapAjustify(a,0);  //(3)调整
        }                       // } //endfor
    }
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        int a[]= {7,3,5,8,9,1,2,4,6};
        cout<<"before :"<<endl;
        print(a,9);
        heap_sort(a,9);
        cout<<"after:"<<endl;
        print(a,9);
        system("pause");
        return 0;
    }
    heap_sort

    堆是一棵完全二叉树,满足二叉树的所有性质;

    对于一颗高度为h的堆,调整堆的时间为O(h);

    7.归并排序

    自底向上:将序列看成是n个长度为1的子序列,两两归并。

    自顶向下:将序列一分为二,然后递归求解

         对两堆排好序且正面朝上的扑克,每次从表面选择较小一张,直到所有牌取完。

     1 // merge_sort.cpp : 定义控制台应用程序的入口点。
     2 //
     3 
     4 #include "stdafx.h"
     5 #include <iostream>
     6 
     7 using namespace std;
     8 
     9 void print(int a[],int n)
    10 {
    11     for (int i=0;i<n;i++)
    12     {
    13         cout<<a[i]<<" ";
    14     }
    15     cout<<endl;
    16 }
    17 void merge(int a[],int temp[],int llow,int rlow,int rend)//利用额外的数组来组合
    18 {
    19     int NumEle = rend-llow+1;
    20     int lend = rlow-1;
    21     int position=llow;
    22     while (llow<=lend&&rlow<=rend)
    23     {
    24         if (a[llow]<=a[rlow])temp[position++]=a[llow++];
    25         else temp[position++]=a[rlow++];
    26     }
    27     while(llow<=lend)temp[position++]=a[llow++];
    28     while(rlow<=rend)temp[position++]=a[rlow++];
    29     for (int i=0;i<NumEle;i++,rend--)
    30         a[rend]=temp[rend];
    31 
    32 }
    33 void merge_sort_1(int a[],int temp[],int low,int high)//找中点,分别递归
    34 {
    35     if(low>=high)return;
    36     int middle = (low+high)/2;
    37     merge_sort_1(a,temp,low,middle);
    38     merge_sort_1(a,temp,middle+1,high);
    39     merge(a,temp,low,middle+1,high);
    40 }
    41 
    42 
    43 void merge_sort(int a[],int size)//申请空间
    44 {
    45     int *temp = NULL;
    46     temp = new int[size];
    47     if (temp!=NULL)
    48     {
    49         merge_sort_1(a,temp,0,size-1);
    50         delete []temp;
    51     }
    52 
    53 }
    54 
    55 int _tmain(int argc, _TCHAR* argv[])
    56 {
    57     int a[]={7,3,2,6,8,4,5,9,1};
    58     print(a,9);
    59     merge_sort(a,9);
    60     print(a,9);
    61     system("pause");
    62     return 0;
    63 }
    merge_sort

    *分治法:对于结构是递归的算法,将原问题分解为多个规模小且类似原问题的子问题,递归求解他们,再将它们的解组合起来构成原问题的解。

    采用递归式来描述递归算法的划分,求解得到简单递归的渐进界(主方法)。还有递归树法,两种常用分析法

    8.计数排序

    思想:对于每个输入元素x,确定比它小的数,就可以将它放到正确的位置上了。计数排序假设输入数据都属于一个小区间内的整数。

     1 // CountSort.cpp : 定义控制台应用程序的入口点。
     2 //
     3 
     4 #include "stdafx.h"
     5 #include <iostream>
     6 #include <memory>
     7 
     8 using namespace std;
     9 
    10 void print(int a[],int len)
    11 {
    12     for (int i=0;i<len;i++)
    13     {
    14         cout<<a[i]<<" ";
    15     }
    16     cout<<endl;
    17 }
    18 
    19 int findmax(int a[],int size)
    20 {
    21     int max=a[0];
    22     for (int i=1;i<size;i++)
    23     {
    24         if (a[i]>max)max=a[i];
    25     }
    26     return max;
    27 }
    28 
    29 void countsort(int a[],int len,int &max)
    30 {
    31     int* b=(int *)malloc(len*sizeof(int));
    32     int* c=(int *)malloc((max+1)*sizeof(int));
    33     memset(b,0,len*sizeof(int));
    34     memset(c,0,(max+1)*sizeof(int));
    35     /*
    36     这里for有点问题,i应该从0开始,但是结果有点误差,c[]正确.
    37     从1开始结果正确,但c[]错,且说不通。
    38     */
    39     for (int i=0;i<len;i++)
    40         c[a[i]]=c[a[i]]+1;
    41     //c[] contains the number of elements equal to i.
    42     print(c,max+1);
    43 
    44     for (int j=1;j<=max;j++)
    45         c[j]=c[j]+c[j-1];
    46     //c[] now contains the number of elements less then or equal to i.
    47     print(c,max+1);
    48 
    49     for (int k=len-1;k>=0;--k)
    50     {
    51         /*
    52          1st:k=7,a[k] is the value of array;
    53              c[a[k]] is the number of elements that <= a[k];
    54              b[c[a[k]]] means a[k] was put to array b, its 
    55              position is c[a[k]].because there are c[a[k]]-1
    56              elements before it.
    57          ...
    58         */
    59         b[c[a[k]]]=a[k];
    60         c[a[k]]-=1;
    61     }
    62     cout<<"after:"<<endl;
    63     print(b,len);
    64     cout<<endl;
    65     free(b);
    66     free(c);
    67 }
    68 
    69 int _tmain(int argc, _TCHAR* argv[])
    70 {
    71     int a[]={2,5,3,0,2,3,0,3};
    72     cout<<"before:"<<endl;
    73     print(a,8);
    74 
    75     int max=findmax(a,8);
    76     countsort(a,8,max);
    77     system("pause");
    78     return 0;
    79 }
    View Code

    总时间代价为theta(n+k),当k=theta(n)时,运行时间为theta(n).它不是比较排序,所以下界由于n*(lgN)。稳定排序。

    9.基数排序

    基数排序是通过“分配”和“收集”过程来实现排序

    RADIX_SORT(A,d)

    for i <- 1 to d

      do use a stable sort to sort array A on digit i

    // radix_sort.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <iostream>
    #include <math.h>
    using namespace std;
    
    void print(int a[],int size)
    {
        for (int i=0;i<size;i++)
        {
            cout<<a[i]<<" ";
        }
        cout<<endl;
    }
    
    
    
    int findmax(int a[],int &size)
    {
        int max=a[0];
        for (int i=1;i<size;i++)
        {
            if (a[i]>max)max=a[i];
        }
        return max;
    }
    // 算出数的位数
    int ele_digit(int element)
    {
        int digit=0;
        do 
        {
            element/=10;
            digit++;
        } while (element!=0);
        return digit;
    }
    
    int kth_digit(int number,int kth)
    {
        number/=pow(10.0,kth);//砍掉前 kth-1 位
        return number%10;
    }
    /*
    输入元素位数大小不确定,就要求最大数的位数
    */
    void radix_sort(int a[],int size)
    {
        int *temp[10];
        /*
        指针数组,每一个指针指向一个数组.因为个位数一般是从0-9,所以
        这里为10
        */
        int count[10]={0,0,0,0,0,0,0,0,0,0};//记录每个箱子装多少个元素
        int max=findmax(a,size);
        int maxdigit=ele_digit(max);//得到最大数的位数
        for (int i=0;i<10;i++)//初始化temp,是二维数组
        {
            temp[i]=(int *)malloc(size*sizeof(int));//每个temp变量指向一个6个元素的数组
            memset(temp[i],0,size*sizeof(int));
        }
         for (int i=0;i<maxdigit;i++)//对a[]遍历maxdigit次
         {
            //memset(count,0,size*sizeof(int));
            for (int j=0;j<size;i++)//记录元素个数
            {
                int xx=kth_digit(a[j],i);//返回number的第k位数
                temp[xx][count[xx]]=a[j];//此处有问题,我调试不出来。哪位仁兄帮帮忙
                count[xx]++;//当前处理位相同的数++
            }
            int index=0;
            for (int j=0;j<10;j++)//回收
            {
                for (int k=0;k<count[j];k++)
                {
                    a[index++]=temp[j][k];
                }
            }
    
         }
         for (int i=0;i<10;i++)
         {
             free(temp[i]);
         }
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        int a[]={22,32,19,53,47,29};
        cout<<"before:"<<endl;
        print(a,6);
        radix_sort(a,6);
        cout<<"after:"<<endl;
        print(a,6);
        system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    JWPlayer Uncaught Error: Invalid SRT file
    京东电商API
    map, string 强大的STL
    VFL演示样例
    sizeof小览
    Java中httpClient中三种超时设置
    Windows下Mysql5.6启用监控执行脚本的日志
    实时监控MySql状态
    实时监控mysql数据库变化
    SVN命令使用详解
  • 原文地址:https://www.cnblogs.com/lp3318/p/4711012.html
Copyright © 2011-2022 走看看