#include <iostream>
using namespace std;
/*
*<<直接插入排序>>
* 为了实现N个数的排序,将后面N-1个数依次插入到前面已排好的子序列中,
*假定刚开始第1个数是一个已排好序的子序列。经过N-1趟就能得到一个有序序列。
*****时间复杂度:最好情况O(n),最坏情况O(n^2),平均情况O(n^2).
*****空间复杂度:O(1)
*****稳定性:稳定
*/
void InsertSort( int* p, int nLen )
{
int nTemp;
for(int i=1; i<nLen; ++i)
{
nTemp = *(p+i);
for(int j=i; j>0; --j)
{
if( nTemp < *(p+j-1) )
{
*(p+j) = *(p+j-1);
*(p+j-1) = nTemp;
}else{
break;
}
}
}
}
/*
*<<折半插入排序>>
* 与直接插入排序不同的是,折半插入排序不是边比较边移动,而是将比较和移
*动操作分离出来,即先折半查找出元素的待插入位置,然后再统一地移动待插入位
*置之后的所有元素。不难看出折半插入排序仅仅是减少了比较的次数。
*****时间复杂度:O(n^2)
*****空间复杂度:O(1)
*****稳定性:稳定
*/
void BinaryInsertSort( int arr[], int nLen )
{
int nHigh,nLow,nMid,i,j,nTemp;
for(i=1; i<nLen; ++i)
{
nTemp = arr[i];
nLow = 0;
nHigh = i-1;
while( nLow<=nHigh)
{
nMid = (nLow+nHigh)/2;
if(arr[nMid]>nTemp)
{
nHigh = nMid-1;
}else{
nLow = nMid+1;
}
}
for(j=i; j>nMid; --j)
{
arr[j] = arr[j-1];
}
arr[nMid] = nTemp;
}
}
/*
*<<希尔排序>>
* 希尔排序通过比较相距一定间隔的元素,即形如L[i,i+d,i+2d,...i+kd]的序列
*然后缩小间距,再对各分组序列进行排序。直到只比较相邻元素的最后一趟排序为
*止,即最后的间距为1。希尔排序有时也叫做*缩小增量排序*
*****时间复杂度:依赖于增量序列的选择,但最坏情况才为O(N^2)
*****空间复杂度:O(1)
*****稳定性:不稳定
*/
void ShellSort( int arr[], int nLen )
{
int i, j, dk;
int nTemp;
for(dk=nLen/2; dk>0; dk/=2)
{
for(i=dk; i<nLen; ++i)
{
nTemp = arr[i];
for(j=i-dk; j>=0; j-=dk)
{
if(arr[j]>nTemp)
{
arr[j+dk] = arr[j];
arr[j] = nTemp;
}
}
}
}
}
/*
*<<冒泡排序>>
* 冒泡排序的基本思想是从后往前(或从前往后)两两比较相邻元素的值,若为
*逆序,则交换它们,直到序列比较完。我们称它为一趟冒泡。每一趟冒泡都会将一
*个元素放置到其最终位置上。
*****时间复杂度:最好情况O(n),最坏情况O(n^2),平均情况O(n^2)
*****空间复杂度:O(1)
*****稳定性:稳定
*/
void BubbleSort( int arr[], int nLen )
{
bool flag = false;
for(int i=0; i<nLen-1; ++i)
{
flag = false;
for(int j=nLen-1; j>i; --j)
{
if(arr[j-1]>arr[j])
{
flag = true;
arr[j-1] = arr[j-1]^arr[j];
arr[j] = arr[j-1]^arr[j];
arr[j-1] = arr[j-1]^arr[j];
}
}
if( !flag )
{
return;
}
}
}
/*
*<<快速排序>>
* 快速排序是对冒泡排序的一种改进。其基本思想是基于分治法:在待排序表L[n]
*中任取一个元素pivot作为基准,通过一趟排序将序列划分为两部分L[1...K-1]和
*L[k+1...n],是的L[1...k-1]中的所有元素都小于pivot,而L[k+1...n]中所有元素
*都大于或等于pivot。则pivot放在了其最终位置L(k)上。然后,分别递归地对两个子
*序列重复上述过程,直至每部分内只有一个元素或空为止,即所有元素放在了其最终
*位置上。
*****时间复杂度:快排的运行时间与划分是否对称有关,最坏情况O(n^2),最好情况
*O(nlogn),平均情况为O(nlogn)
*****空间复杂度:由于需要递归工作栈,最坏情况为O(n),平均情况为O(logn)
*****稳定性:不稳定
*/
int Partition(int a[], int low, int high)
{
int pivot = a[low];
while(low<high)
{
while(low<high && a[high]>=pivot)
{
--high;
}
a[low] = a[high];
while(low<high && a[low]<=pivot)
{
++low;
}
a[high] = a[low];
}
a[low] = pivot;
return low;
}
void QuickSort(int a[], int low, int high)
{
if(low<high)
{
int pivotPos = Partition(a, low, high);
QuickSort(a, low, pivotPos-1);
QuickSort(a, pivotPos+1, high);
}
}
/*
*<<简单选择排序>>
* 选择排序的算法思想很简单,假设序列为L[n],第i趟排序即从L[i...n]中选择
*关键字最小的元素与L(i)交换,每一趟排序可以确定一个元素的最终位置。经过n-1
*趟排序就可以使得序列有序了。
*****时间复杂度:始终是O(n^2)
*****空间复杂度:O(1)
*****稳定性:不稳定
*/
void SelectedSort( int a[], int n )
{
for(int i=0; i<n-1; ++i)
{
int minPos = i;
for(int j=i+1; j<n; ++j)
{
if(a[j]<a[minPos])
{
minPos = j;
}
}
if( minPos != i)
{
a[i]=a[i]^a[minPos];
a[minPos]=a[i]^a[minPos];
a[i]=a[i]^a[minPos];
}
}
}
/*
*<<堆排序>>
* 堆排序是一种树形选择排序方法,在排序过程中,将L[n]看成是一棵完全二叉
*树的顺序存储结构,利用完全二叉树中双亲节点和孩子节点之间的内在关系,在当
*前无序区中选择关键字最大(或最小)的元素。堆排序的思路是:首先将序列L[n]
*的n个元素建成初始堆,由于堆本身的特点(以大根堆为例),堆顶元素就是最大
*值。输出堆顶元素后,通常将堆底元素送入堆顶,此时根结点已不满足大根堆的性
*质,堆被破坏,将堆顶元素向下调整使其继续保持大根堆的性质,再输出堆顶元素。
*如此重复,直到堆中仅剩下一个元素为止。
*****时间复杂度:O(nlogn)
*****空间复杂度:O(1)
*****稳定性:不稳定
*/
void AdjustUp( int arr[], int i, int nLen )
{
int nTemp = arr[i];
for(int largest=2*i+1; largest<nLen; largest=2*largest+1)
{
if(largest!=nLen-1 && arr[largest]>arr[largest+1])
++largest;
if( nTemp > arr[largest] )
{
arr[i] = arr[largest];
i = largest;
}else{
break;
}
}
arr[i] = nTemp;
}
void BuildHeap( int arr[], int nLen )
{
for(int i=nLen/2-1; i>=0; --i)
AdjustUp(arr,i,nLen);
}
void SortHeap( int arr[], int nLen)
{
BuildHeap(arr, nLen);
for(int i=nLen-1; i>0; --i)// n-1趟的交换和建堆过程
{
arr[0] = arr[0]^arr[i];
arr[i] = arr[0]^arr[i];
arr[0] = arr[0]^arr[i];
AdjustUp(arr, 0, i);
}
}
int main( int argc, char *argv[])
{
int arr[] = {9,6,7,4,2,5,3,1,8};
int nLen = sizeof(arr)/sizeof(int);
//InsertSort(arr, nLen);
//BinaryInsertSort(arr, nLen);
//ShellSort(arr, nLen);
//BubbleSort(arr, nLen);
//SortHeap(arr, nLen);
// SelectedSort(arr,nLen);
QuickSort(arr, 0, nLen-1);
for(int i=0; i<nLen; ++i)
{
cout<<*(arr+i)<<' ';
}cout<<endl;
return 0;
}
c++内部排序算法
最新推荐文章于 2021-08-21 23:37:46 发布