数据结构基础排序

需求:要对 3,5,2,7,9,8,6 这组数据进行排序。

1、冒泡排序

冒泡排序会对相邻的两个数据进行比较,每一次冒泡都会让至少一个元素移动到他应该在的位置。如下图所示,

第一次冒泡两两比较,如果左边>右边则进行交换, 9最大,最后被移动到数组的最顶端。

第二次冒泡,只需要对2,3,5,7,6,8 进行两两比较,8最大应该将它放在倒数第二个位置。

依次类推,经过n-1次冒泡,就可以将所有的数据放到正确的位置。

26f4ca284c870e83cdbb376284d305ae387.jpg

示例代码:

public class Bubble {
	/**
	 * 冒泡排序 效率O(N2)
	 * @param a
	 */
	public void bubbleSort(int[] a) {
		/**
		 * 1、定义两个变量out, in; out未排好序的数据的最大索引,
		 * 通过控制in对剩余未排好序的数据进行两两比较,将最大的数据移动到剩余数据中索引最大的位置。
		 * 2.外层循环out从a.length - 1到1
		 * 3.内层循环in从 0到out-1
		 * 4.比较in>in+1? 是 交换
		 */
		for (int out = a.length - 1; out > 0; out--){
			// outer loop (backward)两两比较
			for (int in = 0; in < out; in++)
				if (a[in] > a[in + 1])
					swap(a,in, in + 1);//交换
		}

	}
	/**
	 * 交换
	 * @param a
	 * @param one
	 * @param two
	 */
	private void swap(int[] a,int one, int two) {
		int temp = a[one];
		a[one] = a[two];
		a[two] = temp;
	}

	/**
	 * 打印数组
	 * @param arr
	 */
	public void display(int[] arr){
		for (int i=0;i < arr.length;i++){
			System.out.print(arr[i]);
			if (i == (arr.length-1)){
				System.out.print("   \n");
			}else{
				System.out.print("   ");
			}

		}
	}
	public static void main(String[] args) {
		int[] arr = {3,5,2,7,9,8,6};
		Bubble bubble = new Bubble();
		bubble.bubbleSort(arr);
		bubble.display(arr);
	}
}

 

2、选择排序

选择排序改进了冒泡排序,将必要的交换次数从 O(N2)减少到O(N)。不幸的是比较的次数仍然保持为O(N2),不过,选择排序仍然为数据排序提供了一种重要的改进,因为他减少了交换的时间,有时候交换的时间比比较的时间更为重要。

选择排序第一次从数组中选择最小的元素放在第1个位置,第二次从剩下的数据中选择最小的数据移动到第2个位置,依次类推,经过n次选择,就可以将整个数组变成有序。

示例代码:

public class Select {
    public void sort(int[] a) {
        /**
         * out未排好序的数据中最左端的数据
         * in是out后面的数据
         * min初始值为out 通过in的增长与min比较获得未排好序的数据最小的值
         */
        int out, in, min;

        for (out = 0; out < a.length - 1; out++)
        {
            min = out;//默认最小的元素为out,也就是剩余元素最左端的索引
            //通过循环找到剩余的元素最小的
            for (in = out + 1; in < a.length; in++)
                if (a[in] < a[min]) // if min greater,
                    min = in; // we have a new min

            swap(a,out, min); // swap them
        }
    }

    /**
     * 交换
     * @param a
     * @param one
     * @param two
     */
    private void swap(int[] a,int one, int two) {
        int temp = a[one];
        a[one] = a[two];
        a[two] = temp;
    }
    public static void main(String[] args) {
        int[] arr = {3,5,2,7,9,8,6};
        Select select = new Select();
        select.sort(arr);
        select.display(arr);
    }
    /**
     * 打印数组
     * @param arr
     */
    public void display(int[] arr){
        for (int i=0;i < arr.length;i++){
            System.out.print(arr[i]);
            if (i == (arr.length-1)){
                System.out.print("   \n");
            }else{
                System.out.print("   ");
            }

        }
    }
}

3、插入排序

大多数情况下,插入排序是基本排序中最好的一种。插入排序将数组分为已排好序的部分和未排好序的部分,将未排好序的部分最左侧的数据拿出和已排好序的数据进行比较,然后找到合适的位置插入。重复这个过程,直到未排序部分的数据为空为止。

示例代码:

public class Insert {
    /**
     * 在插入排序中
     * 在外层for循环中,out变量从1开始向右移动,它标记了未被排序的数据最左端的数据
     * 在内层循环中,通过控制in遍历已排好序的元素和value比较,直到找到插入的位置
     */
    public void sort(int[] a) {
        for (int out = 1;  out < a.length; out++){
            int value = a[out]; // remove marked item
            int in = out - 1; // start shifts at out
            //查找插入的位置
            for(;in >= 0; -- in){
               if(a[in] > value){
                   a[in + 1] = a[in];//将a[in] 移动到a[out]这个位置
               }else{
                   break;//跳出循环,已找到插入位置为 in+1
               }
            }

            a[in + 1] = value; // 插入元素
        }
    }

    public static void main(String[] args) {
        int[] arr = {3,5,2,2,9,8,6};
        Insert insert = new Insert();
        insert.sort(arr);
        insert.display(arr);
    }

    /**
     * 打印数组
     * @param arr
     */
    public void display(int[] arr){
        for (int i=0;i < arr.length;i++){
            System.out.print(arr[i]);
            if (i == (arr.length-1)){
                System.out.print("   \n");
            }else{
                System.out.print("   ");
            }

        }
    }
}

 

转载于:https://my.oschina.net/suzheworld/blog/3013304

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值