选择、插入排序算法以及优化的C++实现和算法时间复杂度的比较用例

C++算法学习(一)

前言

最近在进行数据结构的学习,在了解了队列、堆栈、图等基础知识之后,决定去跟随潮流,一般来说大多数的程序员采用C++这门语言来进行基本算法的实现,但是由于自己的个人学习经历是从C到Java,因此对C++了解不深,接触之后发现爱上了这门语言感觉是C与Java的完美融合。

排序算法

1. O(n^2)的排序算法

SelectionSort()选择排序

简单叙述这个算法是:假设需求是将数组中的元素从小到大进行排列,那么我们首先需要做的就是将出数组中的第二元素开始到结尾的最小值,很熟悉的套路是遍历然后是同第一个交换,这样就保证了最小的排在了第一位,然后是寻找从第三个到结尾的数据集的最小值然后是同第二个交换依次类推。

小小的总结:

选择排序其实就是通过顺序遍历的方式选择元素,通过交换实现排序,这样的过程执行一次数组长度的遍历之后就完成了排序

评价:由于是经过大量的遍历与交换过程才实现排序,算法执行时间较慢

代码:

///选择排序
template<typename T>

void selectionSort(T arr[],int n){
  for(int i=0;i//选择[i,n)ֵ最小的
    int minIndex=i;
    for(int j=i+1;jif(arr[j]

InsertionSort()插入排序

经典的对于这个算法的描述是类比插扑克牌从而理顺手中牌的方法,我认为如果仅仅这样理解插入排序缺了几分深度和考究。首先还是以arr[n]举例。同样是假定遵守升序规律,我们从手中的arr[1]即第二张牌开始,先和前面一张牌arr[0]进行比较,小的话则进行交换,那么我们需要做的就是将数组中的第二元素开始的其他元素比如arr[i]按照顺序依次和前面的元素进行比较,遍历一直进行到找到前面的数(比入如arr[j])比arr[i]还要小,此时该元素的排序遍历过程立即结束,开始进行该元素arr[i]同arr[j]交换,当所有的元素完成这样的交换遍历过程后则完成插入排序。

小小的总结:

插入排序在于在将无顺序集合的第一个元素通过比较插入有序集合从而实现排序。

评价:由于在算法实现时候遍历的终止条件多,可能先停下遍历查找的几率大,所以相对于选择排序在大数据集合的排序过程表现会相对优异

代码实现

    //插入排序C++函数编写
    template<typename T>
    void insertionSort(T arr[], int n){
      for(int i=0;ifor(int j=i;j>0;j--){
            if(arr[j]1]){
              swap(arr[i],arr[i-1]);
            }
            else break;
        }    
      }
    }  

关于插入排序算法的优化

由于插入排序中涉及swap交换,拥有基础编程经验的码友们都知道,一次交换就涉及到三次赋值例如temp=a[i];->a[i]=a[j];->a[j]=temp;这样就会使得运算的时间变大,但是如果我们的算法只是用赋值来实现…

代码实现

 template<typename T>
  void insertionSortOp(T arr[],int[] n){
    for(int i=0;i//e代表需要排序的元素,先对它进行个备份
      T e =arr[i];
      //j保存元素e应该插入的位置
      int j;
      for(j=i;j>0&&a[j-1]>e;j--){//终止的条件是找到要插入的位置的前一位比e小
        arr[j]=a[j-1];//后移一位腾位置
      }
      arr[j] = e;
    }
  }

选择排序、插入排序、优化后的算法比较

随机产生一个数据集合,然后拷贝三份,比较三种算法算法对于统一数据集的排序时间效率比较
下面给出测试所用工程
选择、插入排序算法以及优化的C++实现和算法时间复杂度的比较用例_第1张图片

main.cpp
#include 
#include 
#include 
#include "Student.h"
#include "SortTestHelper.h"

using namespace std;
///选择排序

template<typename T>

void selectionSort(T arr[],int n){
    for(int i=0;i//选择[i,n)ֵ最小的
        int minIndex=i;
        for(int j=i+1;jif(arr[j]///插入排序算法
template<typename T>
void insertionSort(T arr[],int n){
    for(int i=1;ifor(int j=i;j>0;j--){
            if(arr[j]1])
                swap(arr[j],arr[j-1]);
            else
                break;

        }
    }
}
///对于插入排序算法的优化通过数次拷贝取代交换三次赋值多余的运算量
template<typename T>
void insertionSortOp(T arr[],int n){
    for(int i=0;i//寻找元素arr[i]应该插入的位置
        T e =arr[i];
        //j 保存元素e应该插入的位置
        int j ;
        for(j=i;j>0&&arr[j-1]>e;j--){
            arr[j]=arr[j-1];

        }
        arr[j]=e;
    }
}
///冒泡排序
template<typename T>
void BubbleSort(T arr[],int n){
    //bool swapped;
    for(int i=0;ifor(int j=0;j1&&arr[j+1]1]);
        }
    }

}
///冒泡排序version1
template<typename T>
void BubbleSortv1(T arr[],int n){
    bool swapped;
    do{
        swapped= false;
        for(int i=1; iif(arr[i-1] > arr[i]){
                swap(arr[i-1],arr[i]);
                swapped = true;
            }

        }

        n --;
    }while(swapped);
}
int main()
{
    int n=10000;
    int *arr=SortTestHelper::generateRandomArray(n,0,n);
    int *arr1=SortTestHelper::copyIntArray(arr,n);
    int *arr2=SortTestHelper::copyIntArray(arr,n);
    //int *arr3=SortTestHelper::copyIntArray(arr,n);

    SortTestHelper::testSort("Selection Sort",selectionSort,arr,n);
    SortTestHelper::testSort("Insertion Sort",insertionSort,arr1,n);
    SortTestHelper::testSort("Insertion Sort Optimize",insertionSortOp,arr2,n);
    //SortTestHelper::testSort("Bubble Sortv1",BubbleSortv1,arr3,n);
    delete [] arr;
    delete [] arr1;
    delete [] arr2;
    //delete [] arr3;

    return 0;
}
SortTestHelper.h
#ifndef SELECTIONSORT_SORTTEST_HELPER_H
#define SELECTIONSORT_SORTTEST_HELPER_H
#include 
#include 
#include 
#include 

using namespace std;

namespace SortTestHelper{
    //生成有n个元素的随机数组,每个元素的随机范围为[rangeL,rangeR]
    int * generateRandomArray(int n, int rangeL,int rangeR){
        assert(rangeL <= rangeR);
        int *arr = new int [n];
        srand(time(NULL));//随机树种子
        for(int i=0 ;i// 生成区间范围的随机数
            arr[i] =rand()%(rangeR-rangeL+1)+rangeL;

        }
        return arr;

    }

    template<typename T>
    void printArray(T arr[],int n){
        for(int i;icout<" ";
        }
        cout<return;
    }

    template<typename T>
    bool isSorted(T arr[], int n){
        for(int i=0;i1;i++){
            if(arr[i]>arr[i+1])
                return false;
            else
                return true;
        }
    }
    //测试sort排序算法排序arr数组所得到结果的正确性和算法运行时间
    template<typename T>
    void testSort(const string &sortName, void (*sort)(T[],int),T arr[], int n){
        clock_t startTime =clock();
        sort(arr,n);
        clock_t endTime =clock();
        assert(isSorted(arr,n));
        cout<":"<<double (endTime-startTime)/CLOCKS_PER_SEC<<"s"<return;

    }
    int* copyIntArray(int a[],int n){
        int *arr =new int [n];
        copy(a,a+n,arr);
        return arr;
    }
}

#endif // SELECTIONSORT_SORTTESTHELPER_H


You can get my code from my Github


你可能感兴趣的:(算法)