插入、冒泡、选择、归并、快排代码
本文章仅供提交作业及课内交流,并无实际参考学习价值
因尚未弄清楚值传递与引用传递的具体内容,后面二者排序在自由输入数组时会报错,故此处只附上函数体的代码。
插入排序
void Insert(int a[],int n){ //这是插入升序排序的代码
int i;
int j;
int temp;
for (i = 1; i < n; i++){ //从第二个数字开始排序
temp = a[i]; //将“牌”拿在手中
for (j = i - 1; j >= 0&&a[j] > temp; j--){
a[j+1] = a[j];
}
a[j + 1] = temp; //插入手里的“牌”
}
}
此排序运用扑克牌抓取后排序理解,较为简单。
冒泡排序
void Bubble(int a[],int n){ //这是冒泡生序排序的代码
int i;
int j;
int temp;
for (i = 1; i < n; i++){
for(j = n - 1;j >= i;j--){ //每次运行将最小的一个数“冒出”
if (a[j] > a[j + 1]){ //交换位置
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
}
顾名思义,冒泡排序的理解方法为进行每次运行时,都可以将一个最小(大)的数按照要求冒出来,我们将它安放在指定位置。运行相应的次数后,得到有序数列。
选择排序
void Selection(int a[],int n){ //这是选择生序排序代码
int i;
int j;
int min;
int temp;
for (i = 0; i < n; i++){ //依旧从第二个数字开始排序
min = i; //默认最小值下标为开始处下标
for (j = i; j < n; j++){
if (a[j] < a[min]){
min = j; //交换下标以选出最小数
}
}
if(min != i){ //交换位置
temp = a[i];
a[i] = a[min];
a[min] = temp;
}
}
}
一开始做选择排序的时候,没有选取下标而是将该数字直接换位置,写着写着发现和冒泡排序越来越像。后来参考其他博客,明白需要选取下标,最后进行交换。
归并排序
void Merge(int a[],int left,int mid,int right){ //这是归并生序排序的代码
int temp[100];
int begin1 = left;
int end1 = mid;
int begin2 = mid + 1;
int end2 = right;
int k = 0;
while (begin1 <= end1 && begin2 <= end2){ //合并两个有序数组
if (a[begin1] <= a[begin2]){ //将较小的数输入新数组
temp[k++] = a[begin1++]; //将较小数输入且完成自加
} else {
temp[k++] = a[begin2++];
}
if(begin2 = end2 + 1){
while (begin1 <= end1){ //将剩余数字输入
temp[k++] = a[begin1++];
}
}
if(begin1 = end1 +1){
while (begin2 <= end2){
temp[k++] = a[begin2++];
}
}
}
for (int i = 0, j = left; i < k; i++, j++) { //将temp内数据转存到a中
a[j] = temp[i];
}
}
void Mergesort(int a[],int temp[],int left,int right){ //运用递归实现归并排序
if (right <= left){ //递归跳出条件
return;
}
int mid = (right + left) >> 1; //将数组二分
Mergesort(a,temp,left,mid);
Mergesort(a,temp,mid + 1,right);
Merge(a,temp,left,mid,right);
free(temp);
}
本代码尚未完成调试,切勿照搬
归并排序的算法部分已经完全理解,先从合并两个有序数组开始理解。将对应较小(较大)数置入新的数组储存。
然后更进一步,若是对于两个无序数组,是否就没有办法进行归并排序了呢?
进而联想,若数组内仅有一个元素,必定为有序数组,然后归并排序为二元素数组,再继续向外递推,得到有序数组的排列。
故先用分治思想将数组一次一次二分,得到单一元素后进行归并排序,以递归算法完成程序。
但由于尚未搞定值传递与引用传递的具体内容,本代码未能在主程序成功运行。
快速排序
void Quick(int a[],int left,int right){ //这是快速升序排序的代码
int i = left;
int j = right; //储存开始数据
int key = a[left]; //常规定义
if(left >= right){ //递归跳出条件
return;
}
while (left < right){
while (key <= a[right]){
right--; //向前寻找
}
if (key > a[right]){ //将二者交换
int temp = 0;
temp = a[left];
a[left] = a[right];
a[right] = temp;
left++;
}
while (key >= a[left]){
left++; //向后寻找
}
if(key < a[left]){
int temp = 0;
temp = a[left];
a[left] = a[right];
a[right] = temp;
right--;
}
}
Quick(a, i, left-1); //用同样的方式对分出来的左边的部分进行同上的做法
Quick(a, left+1, j); //用同样的方式对分出来的右边的部分进行同上的做法
}
本代码已经在给定数组的情况下成功运行
我曾经认为快速排序会非常难学,毕竟是应用最多的排序,书中也将其放到了较后的位置。
然而若能很好理解归并排序中的分治思想,快速排序理解没有特别难。
本代码参考另一篇博客的“舞动算法”,下面给出链接:快速排序参考内容
选取一个参考数作为“key”,通过检索整个数组,将比“key”小的数字安放在左边,将比“key”大的数字安放在右边,此后,对于左边和右边新得到的数组,仍然采取相同的办法。以递归算法实现排序,在左右数组仅有一个元素的情况下跳出。最后得到排序好的数列。
近期任务
- 值传递与引用传递
- 归并排序与快速排序修正