排序算法--冒泡排序,归并排序,快速排序
2016-08-29 18:01
405 查看
冒泡排序:
属于交换排序的一种。
很好理解的交换排序是这样的:
这个算法的逻辑是从头到尾扫描元素,将这个元素和它后面的所有元素进行比较,如果有比它更小的,那就交换,最后交换的一定是最小的,然后元素指针i后移,再比较它后边的所有元素。
冒泡算法和这个算法类似,不同之处就在于两个for循环,它是交换相邻两个元素,完成一次内循环,最大的元素就跑到了最后一个位置。代码为:
第一层for循环用来控制已经排好序的元素,第二层for循环,用来将未排好序的元素相邻元素比较。循环次数中,为什么要减一呢,那是因为元素要和它下一个元素比较,如果不减一,数组下标就会越界。
归并排序:
这个排序是用递归来做的。需要定义一个merge()函数(归并函数),这个函数的目的是将两个数组归一为一个有序数组。这个merge()函数的参数有待排序数组nums, 第一个元素下标,中间元素下标,最后一个元素下标。merge函数定义如下:
上边是归并排序的归并部分。还需要定义一个归并排序函数,用来做递归用。
这里需要注意的是,last指针指的是最后一个元素。
快速排序:
快速排序的核心就是有一个pivot,我们叫它“基准”。快速排序和归并排序一样,也是用递归来实现的。
做法是: 先定义两个指针i,j。i指向第一个元素,j指向最后一个元素。先将pivot于j所指向的元素比较,若比它大,j--,若比它小,把j所指向的元素给i,i++;再开始pivot和i所指向的元素比较,若i所指向的元素比pivot大,则将i所指向的元素赋给j,j--。
也就是说先从后向前扫描,找到比它小的,再掉转方向,从前往后扫描,找打比它大的,再掉转方向,直到i和j相遇,算法结束。
这里需要注意的是:
1. 必需有递归结束函数
2. 每扫描一次,也要判断一次i是否小于j
3. 如果元素等于基准,就不移动。
打拳时间到了,先记录这三个算法吧。
若有不对之处,敬请指正。
属于交换排序的一种。
很好理解的交换排序是这样的:
for (int i = 0; i < n; ++i) for (int j = i+1; j < n; ++j) { if (nums[i] > nums[j]) swap(nums[i], nums[j]) }
这个算法的逻辑是从头到尾扫描元素,将这个元素和它后面的所有元素进行比较,如果有比它更小的,那就交换,最后交换的一定是最小的,然后元素指针i后移,再比较它后边的所有元素。
冒泡算法和这个算法类似,不同之处就在于两个for循环,它是交换相邻两个元素,完成一次内循环,最大的元素就跑到了最后一个位置。代码为:
for (int i = 0; i < n - 1; ++i) for (int j = 0; j < n - i -1; ++j) { if (nums[j] > nums[j + 1]) swap(nums[j], nums[j + 1]) }
第一层for循环用来控制已经排好序的元素,第二层for循环,用来将未排好序的元素相邻元素比较。循环次数中,为什么要减一呢,那是因为元素要和它下一个元素比较,如果不减一,数组下标就会越界。
归并排序:
这个排序是用递归来做的。需要定义一个merge()函数(归并函数),这个函数的目的是将两个数组归一为一个有序数组。这个merge()函数的参数有待排序数组nums, 第一个元素下标,中间元素下标,最后一个元素下标。merge函数定义如下:
void merge(int nums[], int first, int mid, int last) { int * temp = new int[last - mid + 1]; int i = first; int j = mid + 1; int k = 0; // 这里是核心,也就是归并 while (i <= mid && j <=last) { if (nums[i] < nums[j]) temp[k++] = nums[i++]; else temp[k++] = nums[j++]; } // 归并完了之后,要判断谁还有剩下的,将剩下的放到数组temp中 while (i <= mid) temp[k++] = nums[i++]; while (j <= last) temp[k++] = nums[j++]; // 然后将temp中的值拷贝到原数组中 i = first; k = 0; while (i <= last) nums[i++] = temp[k++]; }
上边是归并排序的归并部分。还需要定义一个归并排序函数,用来做递归用。
void mergeSort(int nums[], int first, int last) { // 递归函数返回 if (first >= last) return; // 否则,继续细分数组,前一半,后一半 int mid = (first + last) / 2; mergeSort(nums, first, mid); mergeSort(nums, mid + 1, last); // 一前一后都归并排序好了,调用归并函数开始归并 merge(nums, first, mid, last); }
这里需要注意的是,last指针指的是最后一个元素。
快速排序:
快速排序的核心就是有一个pivot,我们叫它“基准”。快速排序和归并排序一样,也是用递归来实现的。
做法是: 先定义两个指针i,j。i指向第一个元素,j指向最后一个元素。先将pivot于j所指向的元素比较,若比它大,j--,若比它小,把j所指向的元素给i,i++;再开始pivot和i所指向的元素比较,若i所指向的元素比pivot大,则将i所指向的元素赋给j,j--。
也就是说先从后向前扫描,找到比它小的,再掉转方向,从前往后扫描,找打比它大的,再掉转方向,直到i和j相遇,算法结束。
void quickSort(int nums[], int first, int last) { if (first >= last) return; // 已数组的第一个元素为基准 int pivot = nums[first]; int i = first; int j = last; // 首先要有大循环的结束条件,那就是 i < j while ( i < j) { while ( i < j && nums[j] >= pivot) j--; nums[i] = nums[j]; while (i < j && nums[i] <= pivot) i++; nums[j] = nums[i]; } nums[i] = pivot; quickSort(nums, first, i - 1); quickSort(nums, i + 1, last); }
这里需要注意的是:
1. 必需有递归结束函数
2. 每扫描一次,也要判断一次i是否小于j
3. 如果元素等于基准,就不移动。
打拳时间到了,先记录这三个算法吧。
若有不对之处,敬请指正。
相关文章推荐
- 排序算法合集(插入排序,折半插入排序,希尔排序,冒泡排序,快速排序,简单选择排序,堆排序,归并排序)
- 基本排序算法(冒泡排序 选择排序 插入排序 快速排序 归并排序 基数排序 希尔排序)
- 几种基本的排序算法(选择排序,冒泡排序,快速排序,归并排序,希尔排序)C语言实现
- 各种排序算法实现——基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- 几种常见的排序算法,选择排序,冒泡排序,希尔排序,堆排序,快速排序,归并排序,基数排序的比较
- 算法分析中最常用的几种排序算法(插入排序、希尔排序、冒泡排序、选择排序、快速排序,归并排序)C 语言版
- 经典排序算法 -----冒泡排序,插入排序,快速排序,归并排序,堆排序
- 排序算法: 冒泡排序, 快速排序,希尔排序,直接插入排序 ,直接选择排序,归并排序,堆排序
- 【Java】八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序 、快速排序、归并排序、堆排序和LST基数排序
- 6种排序算法及其比较 简单选择排序,堆排序,简单插入排序,希尔排序,冒泡排序,快速排序,归并排序
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- python排序算法-冒泡排序,选择排序,直接插入排序,希尔排序,归并排序,快速排序,堆排序
- 笔试面试最常涉及到的12种排序算法(包括插入排序、二分插入排序、希尔排序、选择排序、冒泡排序、鸡尾酒排序、快速排序、堆排序、归并排序、桶排序、计数排序和基数排序)进行了详解。每一种算法都有基本介绍、算
- 排序算法(2)冒泡排序,快速排序,归并排序和基数排序MSD,LSD
- 常用的排序算法(快速排序、插入排序、希尔排序、堆排序、冒泡排序、选择排序、归并排序)
- 常用算法--基本排序算法(冒泡排序,选择排序,插入排序,快速排序,归并排序,桶排序)
- 各种排序算法总结----基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- 常用的排序算法:插入排序,希尔排序,冒泡排序,选择排序,快速排序,归并排序
- 元素排序几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)