#include<cstdio>
/*算法只是比较了元素为整数的内容.大部分的排序只是做了简单的测试.仅供参考.*/
void swap(int *a , int *b)
{
int temp = *b;
*b = *a;
*a = temp;
}
bool less(int a, int b)
{
if(a < b)
return true;
else
return false;
}
//对内部中的元素先找到k值,然后分两块
int partition(int *R, int lo, int hi)
{
int i =lo, j = hi;
int temp = R[lo]; //这里的temp就是需要的空间?
if(i<j){
while(i != j)
{
while(j>i && R[j] > temp) j--; //扫描右边
if(j>i) //交换一部分元素
{
R[i] = R[j];
i++;
}
while(j>i &&R[i]<temp)i++; //扫描左边交换元素.
if(j>i)
{
R[j] = R[i];
j--;
}
}
R[i] = temp;
}
return i;
}
//1.快速排序,也是把数组分成两个数组,当两个数组有序的时候,整个数组的有序
void quickSort(int *R, int lo, int hi)
{
if(lo>=hi)
return;
int mid = partition(R, lo, hi);
quickSort(R, lo, mid-1);
quickSort(R, mid+1, hi);
}
//快速排序测试
void testquicksort()
{
int unorder[] = {44,1,3,22,3,13,45,23,55};
int len = sizeof(unorder)/sizeof(int);
quickSort(unorder, 0, len-1);
for(int i =0 ;i< len;i++)
printf("%d ", unorder[i]);
}
//2.冒泡本质上是一种交换排序
void buble_sort(int *R, int n)
{ int i,j,flag =0;
for(i = n; i>=2; i--)
{
for(j = 2; j<=i; j++)
{
if(R[j-1]>R[j])
{
swap(&R[j-1],&R[j]);
flag = 1;
}
}
if(flag == 0)
return ;
}
}
//二路归并,
void merge(int *R,int *ch, int lo,int mid, int hi)
{
for(int i =lo; i <= hi; i++)
{
ch[i] = R[i];
}
int i =lo; int j = mid+1;
printf("start %d, start %d \n",i,j);
for(int k = lo; k <= hi; k++)
{
printf("ri is %d rj is %d",R[i],R[j]);
if(i>mid)
R[k] = ch[j++];
else if(j>hi)
R[k] = ch[i++];
else if(less(ch[i],ch[j])) //比较的是ch
R[k] = ch[i++];
else
R[k] = ch[j++];
printf("cur R[%d] is %d ch is %d\n",k,R[k],ch[k]);
}
}
/*
* 3.二路归并排序
* 把整个数组分成子数组,对子数组排序后,将有序的子数组归并已将整个数组排序
* */
void mergersort(int *R,int *temparray ,int lo, int hi)
{
if(lo>=hi)return ;
int mid = (lo+hi)/2;
mergersort(R,temparray ,lo, mid);
mergersort(R,temparray, mid+1, hi);
merge(R, temparray,lo, mid, hi);
}
void testmergesort()
{
int unorder[] = {44,1,3,22};
//5,41,3,9,44,21,65,
int len = sizeof(unorder)/sizeof(int);
int *temparray = new int(len);
mergersort(unorder, temparray, 0, len-1);
for(int i =0 ;i< len;i++)
printf("%d ", unorder[i]);
delete []temparray;
}
//基于插入排序的快速排序算法
/*4.shell排序是不稳定的,增量要求没有除1外的公因子.
* */
void shellsort(int *R, int n)
{
int h = 1;
int j ,i;
int temp;
while(h < n/3) //以1, 4, 13, ,40,
h = h*3 +1;
while(h >=1) //当前h为1
{
for(i = h; i<n;i++)//假设前面h项都是有序
{
//temp = R[i];
//j = i - 1;
temp = R[i];
j = i -h; //假设有序
while(j >= 0 && R[j]>temp)
{ R[j+h] = R[j];
j = j-h;
}
R[j+h] = temp;
}
h = h/3;
}
}
//5.选择排序
void selectsort(int *R, int n)
{
if(R == NULL||n<=0)
return;
int min;
for(int i = 0; i < n; i++)
{
min = i;
for(int j=i; j<n; j++)
{
if(less(R[j], R[min]))min = j;
}
swap(&R[i],&R[min]);
}
}
//6.插入排序:每次较大元素都向右移动,当然也可以每次交换两个.
void InsertSort(int *R, int n)
{
int i,j;
int temp = 0;
for( i =1; i<n;i++)
{
temp = R[i]; //当前需要排序的元素
j = i-1; //前面有序的元素个数
while(j>=0 && R[j]>temp) //当比前面的元素小的时候
{
R[j+1] = R[j]; //往后移
--j;
}
R[j+1] = temp; //放在当前位置
}
}
/*
class SortCompare
{
public:
SortCompare(){}
void Random
}*/
//测试插入排序
void testinsert()
{
int R[] = {5,4,2,3,7,1};
int n = sizeof(R)/sizeof(int);
InsertSort(R, n);
for(int i =0 ;i<n;i++)
{
printf("%d,",R[i]);
}
}
void testSelectSort()
{
int R[] = {5,4,2,3,7,1};
int n = sizeof(R)/sizeof(int);
selectsort(R, n);
for(int i =0 ;i<n;i++)
{
printf("%d,",R[i]);
}
}
void testShell()
{
int R[] = {5,4,2,3,7,1};
int n = sizeof(R)/sizeof(int);
shellsort(R, n);
for(int i =0 ;i<n;i++)
{
printf("%d,",R[i]);
}
}
//优先队列:支持两种操作删除最大元素和插入元素.
/*
*可以使用堆是有序的完全二叉树,完全二叉树是满二叉从下往上,从右往左删除元素后得到的.因为它的结构,所以可以直接放到里面
* */
void shift(int R[], int low, int high)
{
int temp = R[low];
int i = low;
int j = 2*i;//i的子节点
while(j <= high)
{
if(j < high && R[j] < R[j+1])
{
j++;
}
if(temp < R[j])
{
R[i] = R[j];
i =j;
j = 2*i;
}else
break;
}
R[i] = temp;
}
/*7.堆排序函数*/
void heapSort(int R[], int n)
{
int temp =0;
/*从底部开始建立大根堆*/
for(int i = n/2; i>=1; i--)
{
shift(R, i , n);
}
//进行排序
for(int j = n; j>=2; j--)
{
temp = R[1];
R[1] = R[j];
R[j] = temp;
shift(R, 1, j-1);
}
}
void testheapSort()
{
int R[] = {5,4,2,3,7,1};
int n = sizeof(R)/sizeof(int);
heapSort(R, 6);
for(int i =0 ;i<n;i++)
{
printf("%d,",R[i]);
}
}
//8.计数排序
//9.基数排序:桶排序每次以0-9排序,从个位到最高位
//10.折半插入排序:对一个有序的序列进行折半查找然后插入
//时间复杂度:快排,希尔排序,归并排序和堆排序,是nlog(n) (快些以nlog(n) 归队)
//而空间复杂度:快速排序是O(log(n)), 归并排序是O(n), 基数排序是O(r_d),其他都是O(1);// 当然直接插入容易变成O(n),而冒泡最好是O(n).以上两个是"容易插","起的好"
//其他细节:1.经过一趟排序可以达到最后位置:交换类(冒泡,快速), 选择类(堆排序, 简单选择排序).
// 2.排序方法的元素次数和原始序列无关-----简单选择排序和折半插入排序
// 3.排序方法与排序趟数和原始序列有关-----交换类排序(冒泡,快速)
//稳定性来说:快速排序, 希尔排序, 选择排序, 堆排序是不稳定的,其他稳定.(心情不稳定,快些选堆朋友聊天)
int main(int argc, char **argv)
{
//testinsert();
//testSelectSort();
//testShell();
// testmergesort();
//testquicksort();
testheapSort();
}