数据结构和算法(Java版)学习笔记之数组的简单排序(五)

数组的简单排序(经典算法)

数组的简单排序有:冒泡排序、选择排序、插入排序三种

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


第二趟排序:

扫描二维码关注公众号,回复: 8568477 查看本文章

除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();
		
	}
}

以上就是关于冒泡排序、快速排序、插入排序的原理及代码实现,希望可以帮助到需要的小伙伴。
之后将开始栈和队列的学习,一起努力吧!

发布了46 篇原创文章 · 获赞 11 · 访问量 3926

猜你喜欢

转载自blog.csdn.net/qq_42197800/article/details/89238774
今日推荐