常用排序算法总结与分析(含全部源码)

来源:互联网 发布:农业大数据方案 编辑:程序博客网 时间:2024/05/18 03:31
#include<iostream>using namespace std;/*************** * 直接插入排序 *算法性能: *稳定 *空间代价:Θ(1) *时间代价: *最佳情况:n-1次比较,2(n-1)次移动,Θ(n) *最差情况: Θ(n2) ***************/void InsertSort(int *a,int n);/***************** *   折半插入排序 *****************/void BinaryInsertSort(int *a ,int n);/****************************************************** *   折半与直接插入排序都是稳定的,时间复杂度都是n^2 ******************************************************/void display(int *a,int n);/***************** *希尔排序 *算法性能: *不稳定 *空间代价:Θ(1) *增量每次除以2递减,时间代价:Θ(n2) *选择适当的增量序列,可以使得时间代价接近Θ(n) *******************/void ShellInsert(int* pDataArray, int d, int iDataNum);void ShellSort(int* pDataArray, int iDataNum);/******************************************** *冒泡排序,稳定的排序 ********************************************/void BubbleSort(int *a,int n);//void BubbleSort(int Array[], int n);/******************************************* *快速排序 *性能分析 *最差情况: *时间代价: Θ(n2) *空间代价: Θ(n) *最佳情况: *时间代价:Θ(nlog n) *空间代价:Θ(log n) *平均情况: *时间代价:Θ(nlog n) *空间代价:Θ(log n) *******************************************/void quickSort(int a[],int left,int right);void quickSort2(int a[],int left,int right);/******************************************* *直接选择排序 *性能分析: *不稳定 *空间代价:O(1) *时间代价:比较次数O(n^2),交换次数n-1,总时间代价O(n^2) *******************************************/ void selectSort(int *a,int n);/****************************************** *堆排序 *算法性能: *建堆:Θ(n) *删除堆顶重新建:Θ(log n) *一次建堆,n次删除堆顶 *总时间代价为Θ(nlog n) *空间代价为Θ(1 *******************************************/ void heapSort(int *a,int n); /*****************************  *归并排序  *算法性能  *稳定  *空间代价:Θ(n)  *总时间代价:Θ(nlog n)  *不依赖于原始数组的输入情况,  *最大、最小以及平均时间代价均为Θ(nlog n)  *****************************/ void mergeSort(int *a,int start,int end);int main(){    int a[8] = {2,1,4,6,3,5,4,7};    //InsertSort(a,8);    //BinaryInsertSort(a,8);    //ShellSort(a,8);    //BubbleSort(a,8);    //quickSort2(a,0,7);    //selectSort(a,8);    //heapSort(a,8);    mergeSort(a,0,7);    display(a,8);    return 0;}//直接插入排序void InsertSort(int *a,int n){    int temp=0;    int j=0;    int i;    for( i=1;i<n;i++){        j=i-1;        temp = a[i];        while((j>=0)&&(a[j]>temp)){            a[j+1] = a[j];            j--;        }        a[j+1] = temp;    }}//输出函数void display(int *a ,int n){    int i;     for(i=0;i<n;i++){        cout<<a[i]<<" ";    }}//折半插入排序void BinaryInsertSort(int *a,int n){    int temp,i,j,left,right,middle;    for(i=1;i<n;i++){        temp = a[i];        left = 0;        right = i-1;       while(left<=right){              //必须要有“=”            middle = (left+right)/2;            if(a[i]>a[middle]){                left = middle + 1 ;            }            else{                right = middle - 1;            }       }       for(j=i-1;j>=left;j--){          //必须要有“=”            a[j+1] = a[j];       }       a[left] = temp;    }}/*********************************************************函数名称:ShellInsert*参数说明:pDataArray 无序数组;*          d          增量大小*          iDataNum为无序数据个数*说明:    希尔按增量d的插入排序*********************************************************/void ShellInsert(int* pDataArray, int d, int iDataNum){    for (int i = d; i < iDataNum; i += d)    //从第2个数据开始插入    {        int j = i - d;        int temp = pDataArray[i];    //记录要插入的数据        while (j >= 0 && pDataArray[j] > temp)    //从后向前,找到比其小的数的位置        {            pDataArray[j+d] = pDataArray[j];    //向后挪动            j -= d;        }        if (j != i - d)    //存在比其小的数            pDataArray[j+d] = temp;    }}/*********************************************************函数名称:ShellSort*参数说明:pDataArray 无序数组;*          iDataNum为无序数据个数*说明:    希尔排序*********************************************************/void ShellSort(int* pDataArray, int iDataNum){    int d = iDataNum / 2;    //初始增量设为数组长度的一半    while(d >= 1)    {        ShellInsert(pDataArray, d, iDataNum);        d = d / 2;    //每次增量变为上次的二分之一    }}/**************************** *冒泡排序 ****************************/void BubbleSort(int *a,int n){    int i,j,temp;    bool flag;//用于记录是否发生交换的标志    for(i=0;i<n-1;i++){            flag = true;            for(j = 1;j<n-i;j++){                if(a[j]<a[j-1]){                   temp = a[j];                   a[j] = a[j-1];                   a[j-1] = temp;                   flag = false;//如果有一趟没有发生交换的话,证明整个排序已经完成就不用在进行下面的冒泡                }            }            if(flag)                return ;        }}/******************************************************** *快速排序 分割算法1,返回轴值的记录 ********************************************************/ int Partition1(int a[],int left ,int right){    //实现对从a[left],到a[right]的分割操作,并返回划分后轴元素的位置    int pivot = a[left];    //选取第一个元素作为轴元素    while(left < right){        while(left<right&&a[right]>pivot){  //从右边开始找到一个小于轴元素的位置            right --;        }        a[left] = a[right];                 //将right位置上的数据放到left(原轴元素)的位置上        while(left<right&&a[left]<=pivot){   /*******等号不能省去***/            left ++;        }        a[right] = a[left];                 //将left位置上的元素移动到right位置上, 此时left位置空出    }        a[left] = pivot;     return left;                        //返回轴元素的位置,实现分治 } int Partition2(int a[],int start,int end){        int pivot = a[start];        int temp;        int left = start,right = end;        while(left<=right){            while(left<=right&&a[left]<=pivot){                left++;                }            while(left<=right&&a[right]>pivot){                right --;            }            if(left<right){                temp = a[left];                a[left] = a[right];                a[right] = temp;                left ++;                right --;            }        }        //cout<<left<<"***"<<right<<endl;        /*****交换轴元素与right位置的值*****/        temp =a[right];        a[right] = a[start];        a[start] = temp;        return right; } void quickSort(int a[],int left,int right){    if(left<right){        int p = Partition1(a,left,right);        quickSort(a,left,p-1);        quickSort(a,p+1,right);        } }  void quickSort2(int a[],int left,int right){    if(left<right){        int p = Partition2(a,left,right);        quickSort2(a,left,p-1);        quickSort2(a,p+1,right);        } } /*******************************************  *直接选择排序  *******************************************/ void selectSort(int *a,int n){    int small,i,j;    for(i=0;i<n;i++){        small = i;   //假设最小的值就是i位置上的值        for(j=i+1;j<n;j++){            if(a[j]<a[small]){                // 如果发现更小的记录,记录它的位置                small = j;            }        }        if(small!=i){            //当发现i位置的值不是最小的时候则进行交换            int temp = a[i];            a[i] = a[small];            a[small] = temp;        }    } }/****************************** *堆排序 ******************************/ void siftDown(int *a,int i ,int n){    int leftChild = 2*i+1;    int rightChild = 2*i+2;    int minRoot = i;    if(n>leftChild&&a[minRoot]<a[leftChild]){        minRoot = leftChild;    }    if(n>rightChild&&a[minRoot]<a[rightChild]){        minRoot = rightChild;    }    if(minRoot!=i){//当根节点不是最小值的时候        int temp = a[i];        a[i] = a[minRoot];        a[minRoot] = temp;        siftDown(a,minRoot,n);//递归对子节点进行调整    } } void buildHeap(int *a,int n){        int p = n/2 -1;//记录非叶子节点的最大下标,因为叶子节点不用进行调整        for(int i=p;i>=0;i--){            siftDown(a,i,n);        } } void heapSort(int *a ,int n){    buildHeap(a,n);//构建最大堆    for(int i = n-1;i>0;i--){        int temp = a[i];    //将堆顶的值跟最后一个值进行交换,这是该元素就被放在了正确的位置上        a[i] = a[0];        a[0] = temp;        siftDown(a,0,i);    } }/**************归并排序*********************///合并一个序列中的两个有序子序列void Merge(int *a,int start,int mid,int end){   // cout<<"s:"<<start<<"  "<<"m:"<<mid<<"  "<<"e:"<<end<<endl;    int len1 = mid - start +1 ;    int len2 = end - mid +1 ;    int i;    int j;    int k;    //临时数组存放a[start,mid]和a[mid+1,end]的值    int * left = new int[len1];    int * right = new int[len2];    for(i=0;i<len1;i++){        left[i] = a[i+start];    }    for(i=0;i<len2;i++){        right[i] = a[i+mid+1];    }    //合并left,right    i = 0; j = 0; k = 0;    for(k = start;k<end;k++){        if(i==len1||j==len2){            break;        }        if(left[i]<=right[j]){            a[k] = left[i];            i++;        }else{            a[k] = right[j];            j++;        }    }    while(i<len1){        a[k] = left[i];        k++;        i++;    }    while(j<len2){        a[k] = right[j];        k++;        j++;    }    delete[] left;    delete[] right;}void mergeSort(int *a,int start,int end){    //cout<<"start:"<<start<<"   "<<"end:"<<end<<endl;    if(start<end){        int mid = (start+end)/2;       // cout<<"start:"<<start<<"   "<<"end:"<<end<<endl;       // cout<<"left"<<" "<<"mid:"<<mid<<"end:"<<end<<endl;        mergeSort(a,start,mid);       // cout<<"right"<<" "<<"mid:"<<mid<<"end:"<<end<<endl;        mergeSort(a,mid+1,end);        Merge(a,start,mid,end);    }}

0 0
原创粉丝点击