您的位置:首页 > 编程语言 > Java开发

Java 选择排序、冒泡排序、快速排序、直接插入排序、Java自带的排序等方法的使用和总结

2017-02-28 20:26 861 查看
1、 选择排序:将一组数据中的最大值(最小值)挑出来放在最后一位,再挑次大值(次小值)放在倒数第二位,像这样依次挑出相应值进行排序的方法就是选择排序。助记方式:想到选择排序,就想起挑苹果,从一堆苹果里面挑出最大的放一边,然后再挑次大的,…,最后挑出最小的,这个顺序得来的方法就是我们说的选择排序。

      挑出最大值(最小值)的方法是元素的逐个比较,这需要一层for循环,而挑出值之后剩下的元素还有最大值(最小值),这样相当于每个元素都要和剩下的元素比较一遍(最后一个元素除外),所以又需要一层for循环。以从小到大排序为例,核心代码如下:

for (int i=0; i<nums.length-1; ++i) {
for (int j=i+1; j<nums.length; ++j) {
if (nums[i] > nums[j]) {
temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}


      选择排序法可能会破坏相等数据间的顺序关系,是不稳定的排序方法。

2、 冒泡排序:顾名思义,这种排序方式像冒泡一样,是交换排序的一种,基本思想是对所有相邻记录的关键字值进行比较,如果是逆序(a[j]>a[j+1]),则将其交换,最终达到有序化。冒泡排序将所有待比较元素分为有序区和无序区,初始状态有序区为空,无序区为所有待比较元素,每经过一趟排序都会使无序区中的最大值进入到有序区,所以对于n个元素来说,最多经过n-1趟排序就可以排好顺序。

      冒泡排序需要两层循环,内层循环使每个无序区的最大值进入有序区,外层循环遍历所有的无序区。

      核心代码如下:

for (int i=0; i<nums.length-1; ++i) {
for (int j=0; j<nums.length-1-i; ++j) {
if (nums[j] > nums[j+1]) {
int temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}


3、 快速排序:是对冒泡排序的改进,排序速度相对较快,基本思想是经过一趟排序将所有数据分为两部分,其中一部分的所有值小于另一部分的所有值,用同样的方法分别处理两部分数据,最终使所有数据有序化。分治思想,递归方法。

具体算法:

(1)选取第一个(可任意取,一般取第一个)元素为枢轴(也叫基准或支点),作为关键数据赋值给X;

(2)设指针i指向队首,指针j指向队尾;

(3)指针j向前搜索(j=j-1),找到第一个小于X的值,两者交换位置;

(4)指针i向后搜索(i=i+1),找到第一个大于X的值,两者交换位置;

(5)重复(3)、(4)步骤,直到i=j,这个位置也是枢轴应该在的位置。

最终,枢轴左边的值都不大于枢轴,右边的值都不小于枢轴。

      核心代码如下:

int temp;
int pivotKey = arr[low];		// 设置枢轴,low相当于指针i,high相当于指针j
while (low < high) {
while((low<high) && (arr[high]>=pivotKey))
--high;			// 从后向前移动high的位置
temp = arr[high];		// 将比枢轴小的值移动到左边
arr[high] = arr[low];
arr[low] = temp;
while((low<high) && (arr[low]<=pivotKey))
++low;			// 从前向后移动low的位置
temp = arr[high];		// 将比枢轴大的值移动到右边
arr[high] = arr[low];
arr[low] = temp;
}
arr[low] = pivotKey;			// 将枢轴移动到正确位置
return low;				// 返回枢轴所在的位置


if (left < right-1) {
int pivot = getPivot(arr, left, right);			// 获取新的序列中的枢轴位置
quickSort(arr, left, pivot-1);				// 递归调用
quickSort(arr, pivot+1, right);
}
return arr;				// 返回排好序的数组


4、 直接插入排序:每次从待排序列里面拿出第一个元素,放到有序区中使有序区仍然有序,第一趟拿第二个数与第一个数比较按大小排序,第二趟拿第三个数与前两个数进行比较按大小排序,…,第(n-1)趟拿第n个数与前(n-1)个数进行比较按大小排序,至此经过(n-1)趟扫描以后就完成了排序。助记方法:直接插入排序的过程和我们玩牌时边取牌边整理手中的牌的过程是一样的。
      需要两层循环嵌套,外层循环从第二个数开始遍历所有待比较的值,内层循环将待比较的值插入到有序队列中的合适位置,使有序队列依然有序。
      核心代码如下:

int j;
for (int i=2; i<nums.length; ++i) {
if (nums[i] < nums[i-1]) {	// 这里是从小到大排序
nums[0] = nums[i];		// 之前定义数组时,int nums[] = {0};,所以nums[0]可作为临时值缓冲
for (j=i-1; nums[0] < nums[j]; --j)
nums[j+1] = nums[j];	// 比待排序大的值依次向后挪
nums[j+1] = nums[0];		// 插入待排序的值
}
}


5、 Arrays.sort()方法:这是API里面的方法,文档解释是:将指定数组按升序排序,是由VladimirYaroslavskiy, Jon Bentley, 和 Joshua Bloch研究出来的双支点的快速排序方法,效率要比传统的单支点的快速排序方法高,时间复杂度为O(nlog(n))。sort()方法有很多重载格式,可以接收任何数据类型进行不同类型的排序。

       以int类型为例代码如下:

Arrays.sort(array);			// array为待排序数组
总结:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐