数据结构之排序算法(二)-冒泡排序及改进

冒泡排序算法需要遍历几次数组。每次遍历都要比较连续相邻的元素,如果某一对相邻元素是降序,则互换它们的值,否则,保持不变。由于较小的值像“气泡”一样逐渐浮想顶部,而较大的值沉向底部,所以叫冒泡排序。

冒泡排序的图解是:

总结一句话就是:连续比较相邻的元素,降序则呼唤。有n个数,共需要比较n-1趟,第i趟,需要比较n-i次。

BubbleSort.java

public class BubbleSort {//时间复杂度O(n^2)

	public static void display(int[] array){
		for(int i=0;i<array.length;i++){
	         System.out.print(array[i]+"\t");
	     }
	     System.out.println();
	}
	//冒泡排序
	public static void bubbleSort(int[] list){
		int n=list.length;
		for(int i=1;i<n;i++){//总共比较n-1趟
			for(int j=0;j<n-i;j++){//第i趟比较n-i次
				if(list[j]>list[j+1]){
					int temp;
					temp=list[j];
					list[j]=list[j+1];
					list[j+1]=temp;
				}
			}

			System.out.print("第"+(i)+"轮排序结果:");
	        display(list);
		}

	}
    public static void main(String args[]){
    	int[] list={25,6,56,24,9,12,55};
    	System.out.println("冒泡排序前的list是:");
    	for(int i=0;i<list.length;i++){
    		System.out.print(list[i]+" ");
    	}
    	System.out.println();
    	bubbleSort(list);//进行冒泡排序
    	System.out.println();
    	System.out.println("冒泡排序后的list是:");
    	for(int i=0;i<list.length;i++){
    		System.out.print(list[i]+" ");
    	}
    }
}

算法分析:

最差的情况下,冒泡排序算法需要进行n-1次遍历。第一次遍历需要n-1次比较,第二次遍历需要n-2次比较,依次进行;因此比较总数为:

(n-1)+(n-2)+...+2+1=n(n-1)/2=O(n2)

冒泡排序的时间复杂度为O(n2)

冒泡算法的改进:

冒泡排序的效率比较低,所以我们要通过各种方法改进。在上例中,第四轮排序之后实际上整个数组已经是有序的了,最后两轮的比较没必要进行。

注意:如果某次遍历中没有发生交换,那么就不必进行下一次遍历,因为所有元素已经排好了。

BubbleImprovedSort.java

public class BubbleImprovedSort {
	public static void display(int[] array){
		for(int i=0;i<array.length;i++){
	         System.out.print(array[i]+"\t");
	     }
	     System.out.println();
	}
	//冒泡排序
    public static void bubbleSort(int[] list){
			int n=list.length;
			boolean NeedNextPass=true;
			for(int i=1;i<n&&NeedNextPass;i++){//总共比较n-1趟,如果某趟遍历中没有交换,那么不需要下次遍历,因为元素以排好
				NeedNextPass=false;
				for(int j=0;j<n-i;j++){//第i趟比较n-i次
					if(list[j]>list[j+1]){
						int temp;
						temp=list[j];
						list[j]=list[j+1];
						list[j+1]=temp;
						NeedNextPass=true;
					}
				}
				System.out.print("第"+(i)+"轮排序结果:");
		        display(list);
			}
		}
	    public static void main(String args[]){
	    	int[] list={25,6,56,24,9,12,55};
	    	System.out.println("改进的冒泡排序:");
	    	System.out.println("排序前的list是:");
	    	for(int i=0;i<list.length;i++){
	    		System.out.print(list[i]+" ");
	    	}
	    	System.out.println();
	    	bubbleSort(list);//进行冒泡排序
	    	System.out.println();
	    	System.out.println("排序后的list是:");
	    	for(int i=0;i<list.length;i++){
	    		System.out.print(list[i]+" ");
	    	}
	    }

}

泛型冒泡排序:

例1:元素实现comparable接口。排序是字符串string,string实现了comparable接口

BubbleGenericTypeSort .java

<span style="font-size:24px;">public class BubbleGenericTypeSort {
	//泛型冒泡排序,使用Comparable对元素进行排序
		public static <E extends Comparable<E>> void bubbleGenericTypeSort(E[] list){
			int n=list.length;
			for(int i=1;i<n;i++){//总共比较n-1趟
				for(int j=0;j<n-i;j++){//第i趟比较n-i次
					if(list[j].compareTo(list[j+1])>0){
						E temp;
						temp=list[j];
						list[j]=list[j+1];
						list[j+1]=temp;
					}
				}
			}
		}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		/*Integer[] list={2,1,56,34,9,6,55,20,37,22}; //泛型的Integer ,包装类都实现了Comparable接口
    	System.out.println("冒泡排序前的list是:");
    	for(int i=0;i<list.length;i++){
    		System.out.print(list[i]+" ");
    	}
    	bubbleGenericTypeSort(list);//进行冒泡排序
    	System.out.println();
    	System.out.println("冒泡排序后的list是:");
    	for(int i=0;i<list.length;i++){
    		System.out.print(list[i]+" ");
    	}*/
		String[] list={"John","Mike","Jack","Bob","Zoo","Meache","Abrow","Richer"}; //泛型的String ,包装类都实现了Comparable接口
    	System.out.println("冒泡排序前的list是:");
    	for(int i=0;i<list.length;i++){
    		System.out.print(list[i]+" ");
    	}
    	bubbleGenericTypeSort(list);//进行冒泡排序
    	System.out.println();
    	System.out.println("冒泡排序后的list是:");
    	for(int i=0;i<list.length;i++){
    		System.out.print(list[i]+" ");
    	}
    }
}

</span>

例2.元素实现自定义的Comparator比较器接口

BubbleComparator.java

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class BubbleComparator {
     public static <E>  void bubbleComparatorSort(List<E> list,Comparator<? super E> comparator){//<? super E>是E的父类
    	 int n=list.size();
 		for(int i=1;i<n;i++){//总共比较n-1趟
 			for(int j=0;j<n-i;j++){//第i趟比较n-i次
 				if(comparator.compare(list.get(j), list.get(j+1))==1){
 				    E temp;
 					temp=list.get(j);
 					list.set(j, list.get(j+1));
 					list.set(j+1, temp);
 				}
 			}
 		}
     }

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        List<GeometricObject> list=new ArrayList<GeometricObject>();
        list.add(new Rectangle(4,5,"矩形4,5"));
        list.add(new Circle(3,"圆3"));
        list.add(new Square(3,"正方形3"));
        list.add(new Rectangle(2,6,"矩形2,6"));
        list.add(new Circle(4,"圆4"));

        System.out.println("冒泡排序前的list是:");
    	for(int i=0;i<list.size();i++){
    		System.out.print(list.get(i).getName()+":"+list.get(i).getArea()+"  ");
    	}
    	bubbleComparatorSort(list, new GeometricObjectComparator());//进行冒泡排序
    	System.out.println();
    	System.out.println("冒泡排序后的list是:");
    	for(int i=0;i<list.size();i++){
    		System.out.print(list.get(i).getName()+":"+list.get(i).getArea()+"  ");
    	}

	}

    public static class GeometricObjectComparator implements Comparator<GeometricObject> {
    	GeometricObjectComparator(){}

		@Override
		public int compare(GeometricObject o1, GeometricObject o2) {
			// TODO Auto-generated method stub
			float area1=o1.getArea();
			float area2=o2.getArea();
			if(area1<area2){
				return -1;
			}
			else if(area1==area2)
				return 0;
			else
				return 1;
		}

    }
}

时间: 2024-11-10 05:35:21

数据结构之排序算法(二)-冒泡排序及改进的相关文章

排序算法&lt;二&gt;冒泡排序

#include<iostream> using namespace std; int arr[]={11,12,51,23,64,23,68,1,12}; void bubbleSort(int arr[]){ for (int i=0; i<9; i++){ for (int j=0; j<8-i; j++) if (arr[j]>arr[j+1]) swap(arr[j], arr[j+1]); } } int main() { bubbleSort(arr); for

数据结构-各类排序算法总结

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

数据结构基础 排序算法(一) 概念篇

本辑将会对笔试面试最常涉及到的12种排序算法(包括插入排序.二分插入排序.希尔排序.选择排序.冒泡排序.鸡尾酒排序.快速排序.堆排序.归并排序.桶排序.计数排序和基数排序)进行详解.每一种算法都有基本介绍.算法原理分析.图解演示.算法代码.笔试面试重点分析.笔试面试题等板块. 一.插入排序 1)算法简介 插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法.它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入.插入排序在实现上,通常

数据结构-各类排序算法总结[续]

各类排序算法总结 三.交换类排序[接上] 2.快速排序 快速排序是通过比较关键码.交换记录,以某个记录为界(该记录称为支点),将待排序列分成两部分.其中,一部分所有记录的关键码大于等于支点记录的关键码,另一部分所有记录的关键码小于支点记录的关键码.我们将待排序列按关键码以支点记录分成两部分的过程,称为一次划分.对各部分不断划分,直到整个序列按关键码有序. 如果每次划分对一个元素定位后,该元素的左侧子序列与右侧子序列的长度相同,则下一步将是对两个长度减半的子序列进行排序,这是最理想的情况! [算法

排序算法之冒泡排序(Java)

 冒泡排序即每次遍历.相邻数字间进行比较,前者大于后者进行交换,不断将最大值后移,直至沉至最后位置:算法关键要点在于确定每次循环的边界: 后面两种算法则是对冒泡排序一定程度上的改良,但相对于其他排序算法,冒泡排序性能依然较差. //冒泡排序 public class Bubble_Sort { //最原始的解法 public void bubble_sort1(int[] data) { int n = data.length; for(int i = 0; i < n; i++) { //

排序算法 之 冒泡排序

之前看到一个题目,大概是:有一个长度为n的数组,数组内的元素取值范围为0到m,且不相等,要求元素经过n次移动后使数组有序(即算法的复杂度为O(n)).看到题目后想了快速排序和归并排序发现并不能满足题目要求,直到有次看书有看到了桶排序然后豁然开朗,所以决定把这些排序算法再写一遍,加深记忆. 约定:之后的文章默认待排序的数组大小都为n,排序结果为由小到大,采用c#作为代码实现. 1.基本的冒泡排序算法: 基本思想: 冒泡排序外层共需要对序列进行n-1次遍历,内层从e[0]到e[n-i](i为外层遍历

【数据结构】——排序算法——1.1、直接插入排序

插入算法很多,无论是在内功修炼,各种笔试面试都是相当有用的.接下来,将陆续将各种排序算法进行练习: 主要分为以下几个部分(其他后面学习补充): 一.插入类排序:1.直接插入排序:2.折半插入排序:3.希尔shell排序: 二.交换类排序:1.冒泡排序 :2.快速排序: 三.选择类排序:1.简单选择: 2.堆排序: 本人多使用Java--开始吧! 首先推荐1.维基百科<排序算法>词条,图文并茂,很形象!2.学习博文<维基百科上的算法和数据结构链接很强大>,资料很多,保存学习! [数据

排序算法之冒泡排序Java实现

排序算法之冒泡排序 一.初级的冒泡排序 import java.util.Arrays; /** * * @title BubbleSort * @describe 冒泡排序 * @author 张富昌 * @date 2016年10月1日下午3:56:30 */public class BubbleSortLow { // 起泡排序是快速排序的基础,但是排序速度较慢. // 基本思想:将序列中第 1 个元素与第 2 个元素进行比较,如前者大于后者,则两个元素交换位置,否则不交换: // 再将第

数据结构-各类排序算法总结[结局]

各类排序算法总结 五.分配类排序->基数排序: 基数排序是一种借助于多关键码排序的思想,是将单关键码按基数分成"多关键码"进行排序的方法.基数排序属于"低位优先"排序法,通过反复进行分配与收集操作完成排序. 对于数字型或字符型的单关键字,可以看成是由多个数位或多个字符构成的多关键字, 此时可以采用这种"分配-收集"的办法进行排序,称作基数排序法.其好处是不需要进行关键字间的比较. 例如:对下列这组关键字{278, 109, 063, 930

数据结构—各类‘排序算法’实现(上)

数据结构中的排序算法分为比较排序,非比较排序.比较排序有插入排序.选择排序.交换排序.归并排序,非比较排序有计数排序.基数排序.下面是排序的具体分类: 1.直接排序 主要思想:使用两个指针,让一个指针从开始,另一个指针指向前一个指针的+1位置,两个数据进行比较 void InsertSort(int* a, size_t size) {      assert(a);      for (size_t i = 0; i < size - 1; i++)      {           int