//*************************************************************************************************************************
***2019年11月25日22:25:51
***这是一个学习的过程!!!
***参考了以下博客,写的很详细!!!
***十大排序算法(C++实现): https://blog.csdn.net/mengyujia1234/article/details/90179896
***轻松搞定十大排序算法(c++版):https://blog.csdn.net/opooc/article/details/80994353
***史上最容易理解的《十大经典算法(动态图展示)》:https://blog.csdn.net/wfq784967698/article/details/79551476
***有前人的基础,我才有更深层的理解!!!
***以下都是经过自己编译器实现了的,做个简单的mark!!!
//**************************************************************************************************************************
/*****************************插入排序*******************************************/
void insertSort(int arr[],int len)
{
//插入排序的思想:
/*从第一个元素开始,去除下一个元素,在已经排序的元素中从后向前扫描,如果前的元素大于该元素,
* 就将其向后移动以为,直到找到位置
* */
for (int i = 1; i < len;i++)
{
int preindex;
int current = arr[i];
for ( preindex = i - 1;preindex >=0 && arr[preindex] > current;preindex -- ) //找位置
{
//前面的大于当前元素
arr[preindex + 1 ] = arr[preindex]; //将前面的向后移动一位
}
//位置找到了,交换
arr[preindex + 1] = current;
}
}
/*****************************希尔排序*******************************************/
void shellSort(int arr[],int len)
{
int gap,i,current,preindex;
for(gap = len / 2; gap > 0 ; gap = gap / 2) //控制增量
{
for(i = gap; i < len; i ++) //里面就是一个插入排序
{
current = arr[i];
for(preindex = i - gap;
preindex >=0 && current <arr[preindex];
preindex = preindex - gap
) //比较大小值
{
arr[preindex +gap ] = arr[preindex];
}
arr[preindex + gap] = current;
}
}
}
/*****************************冒泡排序*******************************************/
void bubleSort(int arr[],int len)
{
int temp=0;
for (int first = 0;first <len -1;first ++)
{
for (int last = len - 1;last >= first;last --)
{
if(arr[last+1 ] < arr[last]) //后面一个比前面一个小,遵循晓得向前跑
{
temp = arr[last];
arr[last] = arr[last+1];
arr[last+1] = temp;
}
}
}
}
void bubleUpdateSort(int arr[],int len)
{
int temp=0;
for (int first = 1;first <len;first ++) //控制趟数
{
int flag = 0 ; //标志位,
for (int last = 0;last <len - first;last ++) //控制交换次数
{
if(arr[last+1 ] < arr[last]) //后面一个比前面一个小,遵循小的向前跑
{
temp = arr[last];
arr[last] = arr[last+1];
arr[last+1] = temp;
flag = 1;
}
}
if(flag == 0) //说明这个没有交换,是有序的
{
return;
}
}
}
/*****************************快速排序*******************************************/
void quickSort(int arr[],int low,int high) //书上的,不能很好的理解
{
int left,right,pivot;
if(low < high)
{
pivot = arr[low]; //选择基准
left = low;
right = high;
while (left < right)
{
while (left < right && arr[right] >= pivot)//找不满足条件的值,然后停止
{
right --;
}
if(left < right)
{
arr[left++] = arr[right];
}
while (left < right && arr[left] <= pivot)//找不满足条件的值,然后停止
{
left ++;
}
if(left < right)
{
arr[right--] = arr[left];
}
arr[left] = pivot; //基准进行归为
quickSort(arr,low,left-1);
quickSort(arr,left+1,high);
}
}
}
void quick_Sort(int arr[],int left, int right) //来自网上,比较容易理解
{
int i, j, t, temp;
if(left > right)
{
return;
}
temp = arr[left]; //temp中存的就是基准数
i = left;
j = right;
while(i != j) //这个是第一遍,完了之后用递归执行已经有序的区间,知道全部有序
{
//顺序很重要,要先从右边开始找
while(arr[j] >= temp && i < j)
j--;
while(arr[i] <= temp && i < j)//再找右边的
i++;
if(i < j)//交换两个数在数组中的位置
{
t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
//最终将基准数归位
arr[left] = arr[i];
arr[i] = temp;
quick_Sort(arr,left, i-1);//继续处理左边的,这里是一个递归的过程
quick_Sort(arr,i+1, right);//继续处理右边的 ,这里是一个递归的过程
}
/*****************************选择排序*******************************************/
void selectSort(int arr[],int len)
{
//每次选择最小的数 并标记其位置
for(int i = 0;i < len; i++)
{
int min=arr[i]; //默认当前为最小
int location = i; //默认标记当前位置
for(int j = i;j < len; j++)
{
if(arr[j] < min) //如果比min还小,则这个数为最新的最小值,要保存起来,并标记
{
min = arr[j];
location = j;
}
}
//遍历完之后 在将arr[i]和最小值进行交换
arr[location] = arr[i];
arr[i] = min;
}
}
/*****************************堆排序*******************************************/
void heapSwap(int *a,int *b)
{
//使用这个将数组的第一个和最后一个元素进行交换
int temp;
temp = *a;
*a= *b;
*b = temp;
}
void max_heapify(int arr[], int start, int end)
{
//建立父节点指标和子节点指标
int dad = start;
int son = dad * 2 + 1;
while (son <= end) //若子节点指标在范围内才做比较
{
if (son + 1 <= end && arr[son] < arr[son + 1])
{
//先比较两个子节点大小,选择最大的
son++;
}
if (arr[dad] > arr[son]) //如果父节点大于子节点代表调整完毕,直接跳出函数
{
return;
}
else //否则交换父子内容再继续子节点和孙节点比较
{
heapSwap(&arr[dad], &arr[son]);
dad = son;
son = dad * 2 + 1;
}
}
}
void heap_sort(int arr[], int len)
{
int i;
//初始化,i从最后一个父节点开始调整
for (i = len / 2 - 1; i >= 0; i--)
{
max_heapify(arr, i, len - 1);
}
for (i = len - 1; i > 0; i--)
{
heapSwap(&arr[0], &arr[i]); //交换,再重新调整,直到排序完毕
max_heapify(arr, 0, i - 1); //再重新调整,直到排序完毕
}
}
/*****************************归并排序*******************************************/
void merge(int array[],int temp[],int leftpos,int rightpos,int rightEnd) //将结果进行排序
{
//这个函数主要是在将有序的数进行合并
int temppos = leftpos; //临时的temp数组中的索引
int leftEnd= rightpos - 1; //左边的末尾端
int arraylen = rightEnd -leftpos + 1; //这个是整个数组的长度
while (leftpos <= leftEnd &&rightpos <= rightEnd) //只要这个条件满足,就一直比较左右两边值的大小
{
if(array[leftpos] < array[rightpos])
{
temp[temppos++] = array[leftpos++]; //左边的小
}
else {
temp[temppos++] = array[rightpos++]; //右边的小
}
}
//这样一来,后面的就是剩下的,
while (leftpos <= leftEnd)
{
temp[temppos++] = array[leftpos++]; //把左边剩余元素全部放进去
}
while (rightpos <= rightEnd)
{
temp[temppos++] = array[rightpos++]; //把右边的剩余元素全部放进去
}
//这样一来,所有的元素全都在temp临时数组中排序完成,现在要赋值给原来的数组
for (int i=0;i<arraylen;i++,rightEnd--)
{
array[rightEnd] = temp[rightEnd];
}
}
void mergerecursive(int array[],int temp[],int low,int high) //局部函数调用
{
if(low>=high)
{
return;
}
//计算分裂点
int middle= (low+high)/2;
mergerecursive(array,temp,low,middle); //把子区间[low,middle]递归并排序
mergerecursive(array,temp,middle+1,high); //吧把子区间[middle+1,high]递归并排序
merge(array,temp,low,middle+1,high); //组合,吧两个有序区间组合为一个有序区间
}
void mergeSort(int array[],int len) //整体函数调用
{
//我要归并排序,两个比较
int *tmp = NULL;
tmp = new int [len];
if(tmp!=NULL)
{
mergerecursive(array,tmp,0,len-1);
delete tmp;
}
}
/*****************************基数排序*******************************************/
int findMax(int array[], int len)
{
//这个是为了查找要排序中最大的位数
int max = 0;
int count = 1;
int temp; //temp来存储位数
for(int i = 0; i <len; i++)
{
while ((temp/10) != 0)
{
temp = array[i] / 10;
count ++;
}
if(count > max)
{
max = count;
}
}
return max; //返回的是最大的位数
}
void baseSort(int array[] ,int len)
{
int *count = new int[10]; //计数器
int *temp = new int [len]; //一个桶能装多少数据
int maxbit = findMax(array,len); //先获得最大位数,最大的位数就是需要排序的次数
for(int i;i < maxbit;i++) //比较的次数
{
//清空桶中的数据
for(int i = 0; i < 10; i++)
{
count[i] = 0;
}
//清空
}
}
void printSort(int arr[],int len)
{
for(int j = 0 ;j < len; j++)
{
cout << " "<<arr[j];
}
cout <<endl;
}
int main()
{
int array[]={10,9,8,7,6,5,4,3,2,45,58,54,56,8,415,1,5,15,898,545,6,5,4,3,2,1,0,10,9,8,7,6,5,4,3,2,1,0};
int len = sizeof (array)/sizeof (array[0]);
// bubleSort(array,len);
// bubleUpdateSort(array,len);
// shellSort(array,len);
// insertSort(array,len);
// quick_Sort(array,0,9);
// selectSort(array,len);
// quickSort(array,0,5);
// heap_sort(array,len);
mergeSort(array,len);
printSort(array,len);
return 0;
}