常用排序算法总结与分析(含全部源码)
来源:互联网 发布:农业大数据方案 编辑:程序博客网 时间: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
- 常用排序算法总结与分析(含全部源码)
- 常用排序算法总结与分析
- 总结几种常用的排序算法(含代码)
- 常用排序算法总结及源码
- 《数据结构与算法分析》排序算法总结
- 【数据结构与算法】内部排序之四:归并排序和快速排序(含完整源码)
- 【数据结构与算法】内部排序之四:归并排序和快速排序(含完整源码)
- 常用排序算法 的分析与对比
- 常用排序算法分析与实现
- 常用排序算法的分析与实现
- 算法与数据结构-常用排序算法总结1-比较排序
- 算法与数据结构-常用排序算法总结2-计数排序
- 算法与数据结构-常用排序算法总结2-桶排序
- Java常用排序算法冒泡排序与选择排序总结
- 【数据结构与算法】内部排序之三:堆排序(含完整源码)
- 【数据结构与算法】内部排序之三:堆排序(含完整源码)
- 【数据结构与算法】内部排序之三:堆排序(含完整源码)
- 【数据结构与算法】内部排序之三:堆排序(含完整源码)
- MyEclipse6.5集成Axis2和部署步骤
- Mybatis错误:Parameter 'XXX' not found. Available parameters are [1, 0, param1, param2]
- mysql 建立索引
- C++类的Constructors,Copy,Assignment,Destruction(二)
- 黑马程序员-Java入门需掌握的30个基本概念
- 常用排序算法总结与分析(含全部源码)
- OCP 1Z0 052 11
- Remove Duplicates from Sorted Array II
- 一种对拉格朗日乘子的直观理解
- leedcode做题总结,题目Reverse Words in a String14/03/05
- 【Leetcode】Word Break II
- 黑马程序员-Java基础语法
- 黑马程序员-Java关键字
- oracle11g倒出空表