排序 交换排序

交换排序

思想:两两比较待排序记录的关键字,发现两个记录的次序相反时,即进行交换。

  1. 冒泡排序

    1).基本思想:将被排序的记录的关键字垂直排列,首先将第一个记录的关键字与第二个记录的关键字进行比较,若前者大于后者,则交换两个记录,然后比较第二个和第三个记录,以此类推,直到第n-1个记录与第n个记录的关键字比较为止。上述过程称为第一趟冒泡排序,其结果使得关键字最大的记录被安排在最后一个记录的位置上。然后进行第二趟冒牌排序,对前n-1个记录进行同样的排序,使得关键字次大的记录被安排在第n-1个记录的位置上。在冒泡的过程中,关键字较小的记录像水中的气泡一样逐渐向上漂浮,而关键字较大的记录好像石块逐渐向下下沉,每次有一块最大的石块沉到底。

2)时间复杂度:O(n2

  • 代码实现:

/// <summary>

/// 冒泡排序

/// </summary>

/// <paramname="arr"></param>

///<returns></returns>

public static int[]bubbleSort(int[] arr)

{

for (int i = 0; i< arr.Length; i++)

{

for (int j =arr.Length-1; j >i; j--)

{

if (arr[j]< arr[j - 1])

{

int t= arr[j];

arr[j]= arr[j - 1];

arr[j- 1] = t;

}

}

}

return arr;

}

/// <summary>

/// 优化冒泡排序

/// </summary>

/// <paramname="arr"></param>

///<returns></returns>

public static int[]yhBubbleSort(int[] arr)

{

for (int i = 0; i< arr.Length; i++)

{

bool exchange= false;

for (int j =arr.Length - 1; j > i; j--)

{

if (arr[j]< arr[j - 1])

{

int t= arr[j];

arr[j]= arr[j - 1];

arr[j- 1] = t;

exchange = true;

}

}

if (!exchange)

break;

}

return arr;

}

2.快速排序

快速排序是一种分区交换排序。他采用了一种分治法策略,分治法的基本思想是:将原问题分解为若干个规模更小但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。快速排序时目前已知的平均速度最快的一种排序方法。

基本思想:从待排序的n个记录中任意选取一个记录Ri(通常选取序列中的第1个记录)作为标准,调整序列中各个记录的位置,使排在Ri前面的记录的关键字都小于Ri的关键字,排在Ri后面的记录的关键字都大于Ri的关键字,我们把这样一个过程称为一次快速排序。在第一次快速排序中,确定了所选的记录Ri最终在序列中的排序位置,同时也把剩余的记录分成了2个子序列。对2个子序列分别进行快速排序,又确定了2个记录在序列中应处的位置,并将剩余的记录分成4个子序列,如此往复下去,当各个子序列的长度为1时,全部记录排序完毕。

示例如下:

设置2个指示器,一个指示器low,指向顺序表的低端(第一个记录所在的位置),一个指示器high,指向书序表的高端(最后一个记录所在位置)。设置2个变量I,j,他们的初值为当前待排序子序列中第一个记录位置好low的下一条记录和最后一条记录的位置号high。将第一个记录作为标准放到临时变量pivot中,使它所占的位置腾空,然后从子序列的两端开始逐步向中间扫描,在扫描的过程中,变量i,j代表当前扫描到左、右两端记录在序列中的位置号。

1)             从序列的左端扫描时,从序列的当前左端i处开始,将标准记录的关键字与Ri的关键字比较,若前者大于等于后者,令i=i+1,继续进行比较,直到i=j或者小于后者。

2)             在序列右端扫描时,从序列的当前右端开始,把标准记录的关键字与记录Rj的关键字比较,若前者小于等于后者,令j=j-1,继续比较,如此下去,直到标准记录的关键字大于Rj的关键字或i大于j(此时所有位置好大于j的记录的关键字都大于标准记录的关键字)。

3)             如果i小于j,交换位置i和j的值。

上述过程反复交替执行,当i≥j时,扫描结束,j便为第1个记录在序列中应放置的位置。

如图所示:

在图中的排序过程中,首先从左向右移动,搜索大于标准值的第1个元素,i=4的位置所对应的元素80大于标准值70;从列表的右端开始,从右向左移动,搜索小于或等于标准值的第1个元素,这里i=10的位置所对应的元素45小于标准值;因为i<j,所以交换i=4和i=10位置上的元素值。这样就完成了第一趟排序的第一次交换。接着继续第二次交换,第二次交换发生在i=6和j=9的位置上,这时他们的值分别为90和60,交换后的结果如果进行二次交换后的那一行所示;接着i继续移动,当i=7时所对应的元素值100大于标准值70,i停止移动,j开始移动,当j移动到6的位置时,j小于i了,这时循环终止。交换标准值和j所在位置的值,完成一趟快速排序。

快速排序的算法的执行时间取决于标准记录的选择。如果每次排序时,所选记录的关键字的值都是当前子序列的“中间数”,那么该记录的排序终止位置在该子序列的中间,这样就把原来的子序列分解成了两个长度基本相等的更小的子序列,在这种情况下,排序的速度最快。最好情况下快速排序的时间复杂度为O(nlog2n)

另一种极端的情况是每次选取的记录的关键字都是当前子序列的“最小数”,那该记录的位置不变,它把原来的序列分成一个空序列和一个长度为原来序列长度减1的子序列,这种情况下时间复杂度为O(n2)。因此若原始记录列序列已“正序”排列,且每次选取的记录都是序列中的第1个记录,即序列中关键字最小的记录,此时,快速排序就变成了“慢速排序”。

由此可见,快速排序时记录的选取是非常重要的,在一般情况下,序列中的各记录的关键字的分布是随机的,所以每次选取当前序列中的第1个记录不会影响算法的执行时间,因此算法的平均比较次数为O(nlog2n)。

快速排序是一种不稳定的排序方法。

代码实现:

///<summary>

/// 快排

/// </summary>

/// <paramname="arr"></param>

/// <paramname="low"></param>

/// <param name="high"></param>

public static void fastSort( ref int[]arr,int low,int high)

{

if (low > high)

{

return;

}

int pivot = arr[low];

int i = low + 1;

int j = high;

int temp;

while (i < j)

{

while (i < j &&arr[i] <= pivot)

{

i++;

}

while (j >= i &&arr[j] >= pivot)

{

j--;

}

if (i < j)

{

temp = arr[i];

arr[i] = arr[j];

arr[j] = temp;

}

}

if (low < j)

{

temp = arr[low];

arr[low] = arr[j];

arr[j] = temp;

}

fastSort(ref arr, low, j - 1);

fastSort(ref arr, j + 1, high);

}

时间: 2024-11-05 19:34:31

排序 交换排序的相关文章

排序——交换排序

三.交换排序 ①冒泡排序 1.基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换. 2.实例 3.java实现 复制代码 package com.sort; //稳定 public class 冒泡排序 { public static void main(String[] args) { int[] a={49,38,65,97,76,13,

内部排序-&gt;交换排序-&gt;起泡排序

文字描述 首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序(L.r[1].key>L.r[2].key),则将两个记录交换位置,然后比较第二个记录和第三个记录的关键字.依次类推,直至第n-1个记录和第n个记录的关键字进行过比较为止.上述过程称为第一趟起泡排序,其结果使得关键字最大的记录被安置到最后一个记录的位置上. 整个起泡排序过程需进行k(k大于等于1且小于n)趟起泡排序,显然判别起泡排序结束的条件应该是排序过程中没有进行过交换记录的操作. 示意图 算法分析 如果待排序序列为&quo

内部排序-&gt;交换排序-&gt;快速排序

文字描述  快速排序是对起泡排序的一种改进.它的基本思想是,通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序. 一趟快速排序描述:假设待排序的序列为{L.r[s], L.r[s+1], - , L.r[t]},首先任意选取一个记录(通常选第一个记录L.r[s])作为枢轴(pivot), 然后按下述原则重新排列其余记录:将所有关键字较它小的记录都安置在它的位置之前,将所有关键字较它大的记录都安置在它

java排序-交换排序-快速排序

优化前(传统): /** * 快速排序 */ @Test public void kuaiSuTest(){ /** * 1.选择一个基点 * 2.从两边开始向基点遍历,与基点比较,大小位置不对的就互换位置 * 3.遍历结束排序完成 */ sort(data,0,data.length-1); System.out.println(Arrays.toString(data)); } public static void sort(int[] data,int low,int height){ i

JavaScript实现常用的排序算法

▓▓▓▓▓▓ 大致介绍 由于最近要考试复习,所以学习js的时间少了 -_-||,考试完还会继续的努力学习,这次用原生的JavaScript实现以前学习的常用的排序算法,有冒泡排序.快速排序.直接插入排序.希尔排序.直接选择排序 ▓▓▓▓▓▓ 交换排序 交换排序是一类在排序过程中借助于交换操作来完成排序的方法,基本思想是两两比较排序记录的关键字,如果发现两个关键字逆序,则将两个记录位置互换,重复此过程,直到该排序列中所有关键字都有序为止,接下来介绍交换排序中常见的冒泡排序和快速排序 ▓▓▓▓▓▓

排序算法总结----比较类排序

概述:排序算法可分为比较性的排序,以及运算性的排序:这里详细介绍这些排序的原理,性能,实现,以及应用场合. 前面是维基百科的介绍,这里介绍几个比较典型的算法. 理论 计算复杂性理论 大O符号 全序关系 列表 稳定性 比较排序 自适应排序 排序网络 整数排序 交换排序 冒泡排序 鸡尾酒排序 奇偶排序 梳排序 侏儒排序 快速排序 臭皮匠排序 Bogo排序 选择排序 选择排序 堆排序 Smooth排序 笛卡尔树排序 锦标赛排序 循环排序 插入排序 插入排序 希尔排序 二叉查找树排序 图书馆排序 Pat

(转)各类排序算法总结

各类排序算法总结 一. 排序的基本概念 排序(Sorting)是计算机程序设计中的一种重要操作,其功能是对一个数据元素集合或序列重新排列成一个按数据元素某个项值有序的序列. 有 n 个记录的序列{R1,R2,…,Rn},其相应关键字的序列是{K1,K2,…,Kn},相应的下标序列为1,2,…,n.通过排序,要求找出当前下标序列1,2,…, n 的一种排列p1,p2, …,pn,使得相应关键字满足如下的非递减(或非递增)关系,即:Kp1≤Kp2≤…≤Kpn,这样就得到一个按关键字有序的记录序列{R

6、排序——数据结构【基础篇】

排序 排序就是将一组杂乱无章的数据按一定的规律排列起来 插入排序--每步将一个待排序的对象,按其关键码大小,插入到前面已经排好序的一组对象适当位置上,直到对象全部插入为止 直接插入排序 时间复杂度: 空间复杂度: 是一种稳定的排序 二分排序 时间复杂度: 空间复杂度: 是一种稳定的排序 希尔排序 时间复杂度: 空间复杂度: 是一种不稳定的排序 交换排序--是在待排序的记录序列中,两两比较待排序记录关键字,并交换不满足要求的偶对,直到整个序列中所有记录都满足要求为止 冒泡排序 时间复杂度: 空间复

十种常见排序算法

1.常见算法分类 十种常见排序算法一般分为以下几种: (1)非线性时间比较类排序:交换类排序(快速排序和冒泡排序).插入类排序(简单插入排序和希尔排序).选择类排序(简单选择排序和堆排序).归并排序(二路归并排序和多路归并排序): (2)线性时间非比较类排序:计数排序.基数排序和桶排序. 总结: (1)在比较类排序中,归并排序号称最快,其次是快速排序和堆排序,两者不相伯仲,但是有一点需要注意,数据初始排序状态对堆排序不会产生太大的影响,而快速排序却恰恰相反. (2)线性时间非比较类排序一般要优于