数组的简单排序(经典算法)
数组的简单排序有:冒泡排序、选择排序、插入排序三种:
1. 冒泡排序:
原理:比较两个相邻的元素,将值大的元素交换至右端。
- 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复第一趟步骤,直至全部排序完成。
- 画个重点解释下(第一趟比较完成后,最后一个数一定是数组中最大的一个数,所以第二趟比较的时候最后一个数不参与比较;
第二趟比较完成后,倒数第二个数也一定是数组中第二大的数,所以第三趟比较的时候最后两个数不参与比较;
依次类推,每一趟比较次数-1;)
- 优点:每进行一趟排序,就会少比较一次,因为每进行一趟排序都会找出一个较大值。
- 时间复杂度: 如果我们的数据正序,只需要走一趟即可完成排序。所需的比较次数C和记录移动次数M均达到最小值,即:Cmin=n-1;Mmin=0;所以,冒泡排序最好的时间复杂度为O(n)。但是如果很不幸我们的数据是反序的,则需要进行n-1趟排序。每趟排序要进行n-i次比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值,所以冒泡排序的最坏时间复杂度为:O(n2) 。综上所述:冒泡排序总的平均时间复杂度为:O(n2) 。
- 代码实现:
实现冒泡排序算法:
package arrayapplication;
/**
* 冒泡排序
* @author 磊大大
*/
public class BubbleSort {
long[] a;
private int nElems;
private int j;
public BubbleSort(int max){
a = new long[max];
nElems = 0;
}
//添加
public void insert(long value){
a[nElems] = value;
nElems++;
}
//显示所有
public void display(){
for(j = 0; j<nElems; j++)
System.out.print(a[j]+" ");
System.out.println();
}
//冒泡排序(升序)
public void bubbleSort(){
int out; //定义外层循环,控制循环次数
int in; //定义内层循环,控制比较交换
for(out = nElems-1; out>1; out--){
for(in = 0; in<out; in++){
if(a[in]>a[in+1])
swap(in, in+1);
}
}
}
//交换
private void swap(int one, int two){
long temp;
temp = a[one];
a[one] = a[two];
a[two] = temp;
}
}
测试类:
package arrayapplication;
/**
* 冒泡入口
* @author 磊大大
*/
public class BubbleSortApp {
public static void main(String[] args){
BubbleSort arr = new BubbleSort(10);
arr.insert(2);
arr.insert(33);
arr.insert(99);
arr.insert(22);
arr.insert(77);
arr.insert(66);
arr.insert(44);
arr.insert(55);
arr.insert(1);
arr.insert(3);
arr.display();
arr.bubbleSort();
arr.display();
}
}
**
2. 选择排序
**
原理:每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕。也就是:每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。基于此思想的算法主要有简单选择排序、树型选择排序和堆排序。(这里只介绍常用的简单选择排序)
- 思想: 给定数组:int[] a={里面n个数据};第1趟排序,在待排序数据a[0]-a[n]中选出最小的数据,将它与a[0]交换;第2趟,在待排序数据a[1]-a[n]中选出最小的数据,将它与a[1]交换;以此类推,第i趟在待排序数据a[i]~a[n]中选出最小的数据,将它与a[i]交换,直到全部排序完成。
- 举例:数组 long[] a={9, 3, 7, 5, 2};
第一趟排序: 原始数据:9 3 7 5 2
最小数据2,把2放在首位,也就是2和9互换位置,
排序结果:2 3 7 5 9
第二趟排序:
除2以外的数据{ 3 7 5 9}进行比较,3最小,
排序结果:2 3 7 5 9
第三趟排序:
除2、3以外的数据{7 5 9}进行比较,5最小,5和7交换
排序结果:2 3 5 7 9
第四趟排序:
除第2、3、5以外的其他数据{7 9}进行比较,7最小,不交换
排序结果:2 3 5 7 9
最后只剩一个数据,排序结束。
**注:**每一趟排序获得最小数的方法:for循环进行比较,定义变量min指向最小数据下标位置,首先假设第一个数为最小,min等于第一个的下标,然后用min所指的下标和其他数据相比,如果出现比min所在位置小的数据,就用min等于那个数据所在位置的下标。全部比较完后将最小的与第一个数据交换位置,如此循环。
- 代码实现:
快速排序算法:
package Quicksort;
/**
* 快速排序(升序)
* @author 磊大大
*
*/
public class Quicksort {
private long[] a;
private int nElems;
private long temp;
public Quicksort(int max) {
a = new long[max];
nElems = 0;
}
//新增
public void insert(long value) {
a[nElems] = value;
nElems++;
}
//显示全部
public void display() {
for(int j = 0; j < nElems; j++)
System.out.print(a[j]+" ");
System.out.println();
}
//快速排序(升序)
public void quickSort() {
int out,in,min;
for(out=0; out<nElems; out++) {
min = out;
for(in=out+1; in<nElems; in++) {
if(a[in] < a[min])
min = in;
}
swap(min, out);
}
}
//交换
private void swap(int one, int two) {
temp = a[one];
a[one] = a[two];
a[two] = temp;
}
}
- 测试:
package Quicksort;
public class QuicksortApp {
public static void main(String[] args) {
Quicksort a = new Quicksort(10);
a.insert(99);
a.insert(55);
a.insert(44);
a.insert(66);
a.insert(33);
a.insert(22);
a.insert(88);
a.insert(30);
a.insert(77);
a.insert(11);
a.display();
a.quickSort();
a.display();
}
}
**
3.插入排序
**
原理:将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
图片演示:
-注: 定义一个第三个变量temp,从下标为1的数开始,将 a[1] 的数据取出到temp,并与a[0]的数比较,若a[0] > a[1],则将a[0]的数据赋值给a[1],temp赋值给a[0];依次类推。
- 代码实现:
package InsertSort;
/**
* 插入排序(升序)
* @author 磊大大
*
*/
public class InsertSort {
private long[] a;
private int nElems;
public InsertSort(int max) {
a = new long[max];
nElems = 0;
}
// 新增
public void insert(long value) {
a[nElems] = value;
nElems++;
}
// 显示全部
public void display() {
for (int j = 0; j < nElems; j++)
System.out.print(a[j] + " ");
System.out.println();
}
//插入排序
public void insertSort() {
int out,in;
long temp;
for(out=1; out<nElems; out++) {
temp = a[out];
in = out;
while(in>0 && a[in-1]>temp) {
a[in] = a[in-1];
in--;
}
a[in] = temp;
}
}
}
- 测试:
package InsertSort;
public class InsertSortApp {
public static void main(String[] args) {
InsertSort a = new InsertSort(10);
a.insert(99);
a.insert(55);
a.insert(44);
a.insert(66);
a.insert(33);
a.insert(22);
a.insert(88);
a.insert(30);
a.insert(77);
a.insert(11);
a.display();
a.insertSort();
a.display();
}
}
**
3.对象的插入排序
**
原理与插入排序一致,所以直接给出代码实例:
- People类:
package ObjectSort;
/**
* People类
* @author 磊大大
*
*/
public class People {
private String lastName;
private String firstName;
private int age;
public People(String lastName, String firstName, int age) {
this.lastName = lastName;
this.firstName = firstName;
this.age = age;
}
public void displayPeople() {
System.out.print("lastName: "+lastName+" | ");
System.out.print("firstName: "+firstName+" | ");
System.out.print("age: "+age);
System.out.println();
}
public String getLast() {
return lastName;
}
public int getAge() {
return age;
}
}
- 对象的插入排序:
package ObjectSort;
/**
* 对象插入排序
*
* @author 磊大大
*
*/
public class ObjectSort {
private People[] a;
private int nElems;
public ObjectSort(int max) {
a = new People[max];
nElems = 0;
}
// 新增
public void insert(String lastName, String firstName, int age) {
a[nElems] = new People(lastName, firstName, age);
nElems++;
}
// 显示全部
public void display() {
for (int j = 0; j < nElems; j++)
a[j].displayPeople();
System.out.println();
}
//插入排序(按姓)
public void objectSortByLastName() {
int out,in;
People temp;
for(out=1; out<nElems; out++) {
in = out;
temp = a[out];
while(in>0 && a[in-1].getLast().compareTo(temp.getLast()) > 0 ) {
a[in] = a[in-1];
in--;
}
a[in] = temp;
}
}
//插入排序(按姓)
public void objectSortByAge() {
int out,in;
People temp;
for(out=1; out<nElems; out++) {
in = out;
temp = a[out];
while(in>0 && a[in-1].getAge() > temp.getAge()) {
a[in] = a[in-1];
in--;
}
a[in] = temp;
}
}
}
- 测试:
package ObjectSort;
public class ObjectSortApp {
public static void main(String[] args) {
ObjectSort a = new ObjectSort(10);
a.insert("g", "g1", 18);
a.insert("f", "f1", 20);
a.insert("e", "e1", 15);
a.insert("d", "d1", 16);
a.insert("c", "c1", 27);
a.insert("a", "a1", 23);
a.display();
System.out.println("---按lastName排序---");
a.objectSortByLastName();
a.display();
System.out.println("---按age排序---");
a.objectSortByAge();
a.display();
}
}
以上就是关于冒泡排序、快速排序、插入排序的原理及代码实现,希望可以帮助到需要的小伙伴。
之后将开始栈和队列的学习,一起努力吧!