<span style="font-size:14px;">/*
冒泡排序
算法:
核心思想是扫描数据清单,寻找出现乱序的两个相邻的项目。当找到这两个项目后
交换项目的位置然后继续扫描。重复上面的操作直到所有的项目都按顺序排好
时间复杂度n*n (n-1)*n/2
*/
void BubblueSortDate(int SortDate[] , int Length)
{
int tempDate = 0;
bool swapFlag = true;
for(int i = 0; i < Length - 1 && swapFlag; i++)
{
swapFlag = false;
for(int j = 0; j < Length - i - 1; j++)
{
if(SortDate[j] > SortDate[j+1])
{
tempDate = SortDate[j];
SortDate[j] = SortDate[j+1];
SortDate[j+1] = tempDate;
swapFlag = true;
}
}
if(!swapFlag)
return ;
}
}
void SortPrint(int SortPrintf[] , int Length )
{
for(int i=0; i<Length; i++)
{
cout<<SortPrintf[i]<<" ";
}
}
/*
快速排序是对起泡排序的一种改进,通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键
字小,则可分别对这两部分继续进行排序,以达到整个序列有序.
交换顺序表L中子表L.r[low..high]的记录,使枢轴记录到位,并返回其所在位置,此时在它之前(后)的记录均不大(小)于它
时间复杂度为 n*logn,其平均性能最好,若初始记录序列按关键字有序或基本有序,快速排序将锐化为起泡排序
*/
int Partition(int SortData[], int low, int high)
{
int tmpData = SortData[low];//用于子表的第一个记录作枢轴记录
int temp=0;
while ( low<high )
{
//从表的两端交替的向中间扫描
while (low<high && SortData[high]>=tmpData)
{
high--;
}
//将比枢轴记录小的记录移到低端
SortData[low] =SortData[high];
while (low<high && SortData[low]<=tmpData)
{
low++;
}
//将比枢轴记录大的记录移到高端
SortData[high] =SortData[low];
}
//枢轴记录到位
SortData[low] =tmpData;
return low;//返回枢轴所在位置
}
void QuickSortData(int SortData[], int low, int high)
{
int offset;
if ( low<high )
{
offset = Partition(SortData, low, high);
QuickSortData(SortData, low, offset-1);
QuickSortData(SortData, offset+1, high);
}
}
//快速排序
void QuickSort(int data[],int low , int high)
{
int i, j, prvotkey;
if(low < high)
{
prvotkey = data[low];//以数组的第一个元素作为基本元素进行划分
i = low;
j = high;
while(i<j)//从数组两端交替的向中间扫描
{
while(i<j && data[j]>=prvotkey)
{
j--;
}
if(i < j)
data[i++] = data[j];//比基准元素小的移到低下标段
while(i<j && data[i]<=prvotkey)
{
i++;
}
if(i < j)
data[j--] = data[i];//比基准元素大的移到高下标段
}
data[i] = prvotkey; //移动基准元素到正确位置
QuickSort(data , low , i-1);//对前半个子表递归排序
QuickSort(data , i+1 , high);//对后半个子表递归排序
}
}
/*
直接插入排序
算法:经过i-1遍处理后,L[1..i-1]己排好序。第i遍处理仅将L[i]插入L[1..i-1]的适当位置,
使得L[1..i]又是排好序的序列。要达到这个目的,我们可以用顺序比较的方法。
首先比较L[i]和L[i-1],如果L[i-1]<=L[i],则L[1..i]已排好序,第i遍处理就结束了;
否则交换L[i]与L[i-1]的位置,继续比较L[i-1]和L[i-2],直到找到某一个位置j(1≤j≤i-1),
使得L[j] ≤L[j+1]时为止
优点:移动元素次数少,只需要一个辅助空间
时间复杂度n*n
当待排序记录的数量n很小时,这是一种很好的排序方法。但是n很大时,则不适合
*/
void InsertSortData(int SortData[], int Length)
{
int tmpData =0;
int i=0;
int j=0;
for(i=1; i<Length; i++)
{
if ( SortData[i] <SortData[i-1])
{
tmpData =SortData[i];
//数据往后移动
for (j=i-1; j>=0 && tmpData<SortData[j]; j--)
{
SortData[j+1] =SortData[j];
}
//将数据插入到j+1位置
SortData[j+1] =tmpData;
}
}
return;
}
/*
拆半插入排序所需要的辅助空间和直接插入排序相同,从时间上比较,折半插入排序仅减少了关键字间的比较次数,而记录的移动次数不变。
因为时间复杂度仍为n*n
*/
void BInsertSortData(int SortData[], int Length)
{
int tmpData =0;
int i=0;
int j=0;
int low;
int high;
int middle;
for(i=1; i<Length; i++)
{
tmpData =SortData[i];
low =0;
high =i-1;
//在r[low..high]中折半查找有序插入的位置
while ( low<=high )
{
middle =(low+high)/2;
if ( tmpData <SortData[middle] )
{
high =middle-1;
}
else
{
low =middle+1;
}
}
//记录后移
for (j=i-1; j>=high+1; j--)
{
SortData[j+1] =SortData[j];
}
SortData[high+1] =tmpData;
}
return;
}
/*
选择排序
算法:首先找到数据清单中的最小的数据,然后将这个数据同第一个数据交换位置;接下来找第二小的数据,再将其同第二个数据交换位置,以此类推。
所需移动的操作次数最少为0,,最大为3(n-1)
然而无论记录的初始排列如何,需要比较的次数相同n(n-1)/2 复杂度为n*n
*/
void SelectSortData(int SortData[], int Length)
{
int tmpData;
int offset =0;
int j=0;
for (int i=0; i<Length-1; i++)
{
offset =0;
tmpData =SortData[i];
for (j=i+1; j<Length; j++)
{
if ( tmpData>SortData[j] )
{
tmpData =SortData[j];
offset =j;
}
}
if( offset >i)
{
SortData[offset] =SortData[i];
SortData[i] =tmpData;
}
}
return;
}
template <class T >
void ShellSort (T Vector[], int arrSize ) {
T temp;
int gap = arrSize / 2; //gap是子序列间隔
while ( gap != 0 ) { //循环,直到gap为零
for ( int i = gap; i < arrSize; i++) {
temp = Vector[i]; //直接插入排序
for ( int j = i; j >= gap; j -= gap )
if ( temp < Vector[j-gap] )
Vector[j] = Vector[j-gap];
else break;
Vector[j] = temp;
}
gap = ( int ) ( gap / 2 );
}
}
/*归并排序
左边小左边,左边++;右边小取右边,右边++*/
template<typename T>
void merge(T array[], int low, int mid, int high)
{
int k;
T *temp = new T[high-low+1]; //申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
int begin1 = low;
int end1 = mid;
int begin2 = mid + 1;
int end2 = high;
for (k = 0; begin1 <= end1 && begin2 <= end2; ++k) //比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
{
if(array[begin1]<=array[begin2])
temp[k] = array[begin1++];
else
temp[k] = array[begin2++];
}
if(begin1 <= end1) //若第一个序列有剩余,直接拷贝出来粘到合并序列尾
memcpy(temp+k, array+begin1, (end1-begin1+1)*sizeof(T));
if(begin2 <= end2) //若第二个序列有剩余,直接拷贝出来粘到合并序列尾
memcpy(temp+k, array+begin2, (end2-begin2+1)*sizeof(T));
memcpy(array+low, temp, (high-low+1)*sizeof(T));//将排序好的序列拷贝回数组中
delete temp;
}
template<typename T>
void merge_sort(T array[], unsigned int first, unsigned int last)
{
int mid = 0;
if(first<last)
{
//mid = (first+last)/2; /*注意防止溢出*/
mid = first/2 + last/2;
//mid = (first & last) + ((first ^ last) >> 1);
merge_sort(array, first, mid);
merge_sort(array, mid+1,last);
merge(array,first,mid,last);
}
}
/*堆排序
a[s]>=a[2*s] && a[s]>=a[2*s+1]*/
template<typename T>
void Max_heap(T a[],int S,int len)
{
int l = 2*S;
int r = 2*S+1;
int maxI = S;
T elem;
if (l < len && a[l] > a[maxI])
{
maxI = l;
}
if (r < len && a[r] > a[maxI])
{
maxI = r;
}
if (maxI != S)
{
elem = a[S];
a[S] = a[maxI];
a[maxI] = elem;
Max_heap(a,maxI,len);
}
}
template<typename T>
void HeapSort(T a[],int n)
{
int i;
T elem;
for (i = n/2;i>=0;i--)
{
Max_heap(a,i,n);
}
for (i= n-1;i>=1;i--)
{
elem = a[0];
a[0] = a[i];
a[i] = elem;
n = n-1;
Max_heap(a,0,n);
}
}</span>
排序算法
最新推荐文章于 2023-02-12 20:42:34 发布