【Java数据结构】排序

简介:

1.冒泡排序

冒泡排序核心思想:

比较两个元素,如果前一个比后一个大则进行交换。经过对每个元素的比较,最后将最大的元素设置成最后一个元素。重复该操作,最后形成从小到大的排序。
for (int i = 0; i < num-1; i++) {
	for (int j = 0; j < num-i-1; j++) {
		if(arr[j]>arr[j+1])
		{
			t=arr[j];
			arr[j]=arr[j+1];
			arr[j+1]=t;
		}
	}
}

深究:

public static void main(String[] args) {
		//不标准的冒泡排序(顺序排序)
		//思想:从第一个向后开始选“候选数”
	    	//每选择一个就找出它后面最小的数替换“候选数”
		/*
		排序过程 int arr[ ]={3,4,7,2,1};
		候选数arr[0]=3
		3,4,7,2,1
		2,4,7,3,1
		1,4,7,3,2
		候选数arr[1]=4
		1,4,7,3,2
		1,3,7,4,2
		1,2,7,4,3
		候选数arr[2]=7
		1,2,7,4,3
		1,2,4,7,3
		1,2,4,3,7
		候选数arr[3]=3
		1,2,4,3,7
		候选数arr[4]=7
		1,2,4,3,7
		end*/
		int n=5,t;
		int arr[ ]={3,4,7,2,1};
		for (int i = 0; i < n-1; i++) {
			for(int j=i+1; j <  n;j++){
				if(arr[j]<arr[i]){
					t=arr[j];
					arr[j]=arr[i];
					arr[i]=t;
				}
			}
		}
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] +" ");
		}
		//结果:1,2,4,3,7
		
		System.out.println("\n"+"-------------------------");
		
		//标准冒泡排序
		//思路:每次将最大的向后排(顺序排序)
		int n2=5,t2;
		int arr2[ ]={3,4,7,2,1};
		for (int i =1; i < n; i++) {
			for(int j=0; j < n-i; j++){
				if(arr2[j]>arr2[j+1]){
					t=arr2[j];
					arr2[j]=arr2[j+1];
					arr2[j+1]=t;
				}
			}
		}
		for (int i = 0; i < arr2.length; i++) {
			System.out.print(arr2[i] +" ");
		}
		//结果:1,2,4,3,7
		
	}

2.选择排序

选择排序的核心思想:
扫描所有元素,得到最小的元素,并将最小的元素与左边第一个元素进行交换。再次扫描除第一位置的所有元素,得到最小的元素,与左边第二个元素进行交换。以此推类。

package cn.deu;

public class SelectArray {

	long [] arr;
    
       int num;

	public SelectArray() {
		arr=new long[50];
	}
    
	public SelectArray(int n){
		arr=new long[n];
	}
	
	//选择排序
	public void SelectSort(){
		int min=0;
		long tamp=0L;
		for (int i = 0; i < num-1; i++) {
			min=i;
			for(int j=i+1;j<num;j++){
				if(arr[j]<arr[min])
					min=j;
			}
			tamp=arr[i];
			arr[i]=arr[min];
			arr[min]=tamp;
		}
	}
	
	//插入
	public void insert(int n){
		/*int i;
		for (i = 0; i < num; i++) {
			if(arr[i]>n)
				break;
		}
		
		for (int j = num; j > i; j--) {
			arr[j]=arr[j-1];	
		}
		arr[i]=n;
		num++;*/
		arr[num++]=n;
	}
	
	//查找
	public int find(int n){
		int lower=0;
		int upper=num;
		int mid=0;
		
		while(true)
		{
			mid=(lower+upper)/2;
			if(arr[mid]==n)
				return mid;
			else
			if(lower>upper)
			return -1;
			else
			{	if(arr[mid]>n)
			    upper=mid-1;
				else
			    lower=mid+1;
			}
		}
	}
	
	//显示
	public void show(){
		for (int i = 0; i < num; i++) {
			System.out.print(arr[i]+" ");
		}
		System.out.println();
	}
	
	//删除
	public void delete(int n){
		if(find(n)==-1)
			System.out.println("没有发现数据,删除失败!");
		else
		{
			for (int i = find(n); i < num; i++) {
				arr[i]=arr[i+1];
			}
			num--;
		}
	}
	
	//修改
	public void change(int n,int m){
		if(find(n)==-1)
			System.out.println("没有发现数据,修改失败!");
		else
		{
			arr[find(n)]=m;
		}
	}
	
}

测试:
package en.edu.Test;

import cn.deu.SelectArray;

public class SelectSortTest {

	public static void main(String[] args) {
		SelectArray sArr=new SelectArray();
		
		sArr.insert(12);
		sArr.insert(123);
		sArr.insert(34);
		sArr.insert(5);
		sArr.insert(9);
		sArr.insert(345);
		
		sArr.show();
		sArr.SelectSort();
		sArr.show();
		
	}


}
结果:
12 123 34 5 9 345 
5 9 12 34 123 345 


3.直接插入排序

核心思想:
原理:将数组分为无序区和有序区两个区,然后不断将无序区的第一个元素按大小顺序插入到有序区中去,最终将所有无序区元素都移动到有序区完成排序。

要点:设立哨兵,作为临时存储和判断数组边界之用。

具体算法描述如下:

//直接插入排序
	public void InsertSort(){
		long select=0L;
		for (int i = 1; i < num; i++) {
			select=arr[i];//取得当前的值
			int j=0;
			for(j=i;j>0&&select<=arr[j-1];j--){
			//从i向前找,只要前面的数据不小于select,都往后移。
				arr[j]=arr[j-1];
			}
	<span style="white-space:pre">		</span>//在i前面找到一个小于select的数据arr[j-1],让后面的arr[j]等于select
	<span style="white-space:pre">		</span>//即让select插入到arr[j-1]后面。
			arr[j]=select;
		}
	}

第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从前向后扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。

插入排序的基本方法是:每步将一个待排序的记录按其关键字的大小插到前面已经排序的序列中的适当位置,直到全部记录插入完毕为止。


4.快速排序

快速排序
原理:不断寻找一个序列的中点,然后对中点左右的序列递归的进行排序,直至全部序列排序完成,使用了分治的思想。

要点:递归、分治

如下所示是一个快速排序的完整例子:
23 13 35 6 19 50 28
[19 13 6] 23 [35 50 28]
[6 13] 19 23 [28] 35 [50]
6 [13] 19 23 28 35 50
6 13 19 23 28 35 50

实现:

int Partition(int r[],int first,int end)//划分 
{
    int i=first,j=end;//初始化待划分区间 
    while(i<j)
    {
        while(i<j&&r[i]<=r[j]) j--;//右侧扫描 
        if(i<j)
        {
               int temp=r[i];r[i]=r[j];r[j]=temp;//将较小记录交换到前面 
               i++;
        }
        while(i<j&&r[i]<=r[j]) i++;//左侧扫描 
        if(i<j)
        {
               int temp=r[i];r[i]=r[j];r[j]=temp;//将较大记录交换到后面 
               j--;
        }
    }
    return i;
}
void QuickSort(int r[],int first,int end)//快速排序 
{
     int pivot;
     if(first<end)
     {
        pivot=Partition(r,first,end);//划分,pivot是轴值在序列中的位置 
        QuickSort(r,first,pivot-1);//求解子问题1,对左侧子序列进行快速排序 
        QuickSort(r,pivot+1,end);//求解子问题2,对右侧子序列进行快速排序 
     }
} 


5.归并排序
原理:将原序列划分为有序的两个序列,然后利用归并算法进行合并,合并之后即为有序序列。

要点:归并、分治

归并排序的执行过程:(*是拆分,#是合并)
     8  3  2  6  7  1  5  4
  *8 3 2 6*         *7 1 5 4*
*8 3*  *2 6*      *7 1*  *5 4*
*8* *3* *2* *6*  *7* *1* *5* *4*
#3 8#   #2 6#    #1 7#   #4 5#
#2 3 6 8#           #1 4 5 7#
    1  2  3  4  5  6  7  8

实现:

void Merge(int r[],int r1[],int s, int m,int t)//合并子序列 
{
     int i=s,j=m+1,k=s;
     while(i<=m&&j<=t)
     {
        if(r[i]<=r[j]) r1[k++]=r[i++];//取r[i]h和r[j]中较小者放入r1[k] 
        else r1[k++]=r[j++];
     } 
     while(i<=m)//若第一个子序列没有处理完,则进行收尾处理 
        r1[k++]=r[i++];
     while(j<=t)//若第二个子序列没有处理完,则进行收尾处理 
        r1[k++]=r[j++];
}


void MergeSort(int r[],int s,int t)//对序列r[s]~r[t]进行归并排序 
{
     int i,m,r1[1010];
     if(s==t) return;
     else
     {
         m=(s+t)/2;
         MergeSort(r,s,m);//求解子问题1,归并排序前半个子序列 
         MergeSort(r,m+1,t);//求解子问题2,归并排序前半个子序列 
         Merge(r,r1,s,m,t);//合并两个有序子序列,结果保存在数组r1中 
         for(i=s;i<=t;i++)//将有序序列传回r中 
         r[i]=r1[i];
     }
} 

6.对象排序(面向对象语言特有)

对实际的类的对象进行排序的过程
Student.java:

package cn.deu;

public class Student {
	//学号
	private int stuNO;
	//姓名
	private String name;
	//性别
	private String sex;
	//年龄
	private int age;
	
	int test;
	public Student(int stuNO, String name, String sex, int age) {
		this.stuNO = stuNO;
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
	
   	public void diaplay()
   	{
	   System.out.print("学号:"+stuNO);
	   System.out.print("姓名:"+name);
	   System.out.print(" 年龄:"+age);
	   System.out.println(" 性别:"+sex); 
       }


	public int getStuNO() {
		return stuNO;
	}


	public void setStuNO(int stuNO) {
		this.stuNO = stuNO;
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	public String getSex() {
		return sex;
	}


	public void setSex(String sex) {
		this.sex = sex;
	}


	public int getAge() {
		return age;
	}


	public void setAge(int age) {
		this.age = age;
	}
	
	
}

操作类:
package cn.deu;

public class StudentArray {
	private Student [] arr;
    
       int num;

	public StudentArray() {
		arr=new Student[50];
	}
    
	public StudentArray(int n){
		arr=new Student[n];
	}
	
	
	//按学号排序
	public void SortByStuNo(){
		int min=0;
		Student tamp=null;
		for (int i = 0; i < num-1; i++) {
			min=i;
			for(int j=i+1;j<num;j++){
				if(arr[j].getStuNO()<arr[min].getStuNO())
					min=j;
			}
			tamp=arr[i];
			arr[i]=arr[min];
			arr[min]=tamp;
		}
	}
	
	//按姓名排序
		public void SortByname(){
			int min=0;
			Student tamp=null;
			for (int i = 0; i < num-1; i++) {
				min=i;
				for(int j=i+1;j<num;j++){
					if(arr[j].getName().compareTo(arr[min].getName())<0)
						min=j;
				}
				tamp=arr[i];
				arr[i]=arr[min];
				arr[min]=tamp;
			}
		}
		
		//按年龄排序
		public void SortByage(){
			int min=0;
			Student tamp=null;
			for (int i = 0; i < num-1; i++) {
				min=i;
				for(int j=i+1;j<num;j++){
					if(arr[j].getAge()<arr[min].getAge())
						min=j;
				}
				tamp=arr[i];
				arr[i]=arr[min];
				arr[min]=tamp;
			}
		}
	
	//插入
	public void insert(Student stu){
		arr[num++]=stu;
	}
	
	//查找
	public int find(String name){
		int i;
		for (i = 0; i < num; i++) {
			if(name.equals(arr[i].getName())){
				break;
			}
		}
		
		if(i==arr.length)
			return -1;
		else
			return i;
	}
	
	//显示
	public void show(){
		for (int i = 0; i < num; i++) {
			arr[i].diaplay();
		}
		System.out.println();
	}
	
	//删除
	public void delete(Student stu){
		if(find(stu.getName())==-1)
			System.out.println("没有发现数据,删除失败!");
		else
		{
			for (int i = find(stu.getName()); i < num; i++) {
				arr[i]=arr[i+1];
			}
			num--;
		}
	}
	
	//删除
		public void delete(String name){
			if(find(name)==-1)
				System.out.println("没有发现数据,删除失败!");
			else
			{
				for (int i = find(name); i < num; i++) {
					arr[i]=arr[i+1];
				}
				num--;
			}
		}
	
	//修改
	public void change(Student stu,Student newstu){
		if(find(stu.getName())==-1)
			System.out.println("没有发现数据,修改失败!");
		else
		{
			arr[find(stu.getName())]=newstu;
		}
	}
}

测试类:
package en.edu.Test;

import cn.deu.Student;
import cn.deu.StudentArray;

public class StudentTest {
	  public static void main(String[] args) {
		StudentArray sArr=new StudentArray();
		
		Student stu1=new Student(54321, "张三", "男", 24);
		Student stu2=new Student(52341, "李四", "男", 21);
		Student stu3=new Student(54564, "王五", "男", 20);
		Student stu4=new Student(59874, "枣儿", "女", 21);


		sArr.insert(stu1);
		sArr.insert(stu2);
		sArr.insert(stu3);
		sArr.insert(stu4);
		
		sArr.show();
		sArr.SortByStuNo();
		sArr.show();
		sArr.SortByname();
		sArr.show();
		sArr.SortByage();
		sArr.show();
	}
}

结果:
学号:54321姓名:张三 年龄:24 性别:男
学号:52341姓名:李四 年龄:21 性别:男
学号:54564姓名:王五 年龄:20 性别:男
学号:59874姓名:枣儿 年龄:21 性别:女


学号:52341姓名:李四 年龄:21 性别:男
学号:54321姓名:张三 年龄:24 性别:男
学号:54564姓名:王五 年龄:20 性别:男
学号:59874姓名:枣儿 年龄:21 性别:女


学号:54321姓名:张三 年龄:24 性别:男
学号:52341姓名:李四 年龄:21 性别:男
学号:59874姓名:枣儿 年龄:21 性别:女
学号:54564姓名:王五 年龄:20 性别:男


学号:54564姓名:王五 年龄:20 性别:男
学号:52341姓名:李四 年龄:21 性别:男
学号:59874姓名:枣儿 年龄:21 性别:女
学号:54321姓名:张三 年龄:24 性别:男

转载请注明出处:http://blog.csdn.net/acmman/article/details/50460690

相关文章
|
1月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
70 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
28天前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
42 1
|
30天前
|
存储 Java
告别混乱!用Java Map优雅管理你的数据结构
【10月更文挑战第17天】在软件开发中,随着项目复杂度增加,数据结构的组织和管理至关重要。Java中的Map接口提供了一种优雅的解决方案,帮助我们高效、清晰地管理数据。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,有效提升了代码质量和维护性。
81 2
|
30天前
|
存储 Java 开发者
Java Map实战:用HashMap和TreeMap轻松解决复杂数据结构问题!
【10月更文挑战第17天】本文深入探讨了Java中HashMap和TreeMap两种Map类型的特性和应用场景。HashMap基于哈希表实现,支持高效的数据操作且允许键值为null;TreeMap基于红黑树实现,支持自然排序或自定义排序,确保元素有序。文章通过具体示例展示了两者的实战应用,帮助开发者根据实际需求选择合适的数据结构,提高开发效率。
61 2
|
13天前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
35 6
|
18天前
|
存储 Java 索引
Java中的数据结构:ArrayList和LinkedList的比较
【10月更文挑战第28天】在Java编程世界中,数据结构是构建复杂程序的基石。本文将深入探讨两种常用的数据结构:ArrayList和LinkedList,通过直观的比喻和实例分析,揭示它们各自的优势与局限,帮助你在面对不同的编程挑战时做出明智的选择。
|
26天前
|
存储 算法 Java
Java 中常用的数据结构
【10月更文挑战第20天】这些数据结构在 Java 编程中都有着广泛的应用,掌握它们的特点和用法对于提高编程能力和解决实际问题非常重要。
25 6
|
28天前
|
存储 Java 开发者
Java中的Map接口提供了一种优雅的方式来管理数据结构,使代码更加清晰、高效
【10月更文挑战第19天】在软件开发中,随着项目复杂度的增加,数据结构的组织和管理变得至关重要。Java中的Map接口提供了一种优雅的方式来管理数据结构,使代码更加清晰、高效。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,帮助开发者告别混乱,提升代码质量。
27 1
|
1月前
|
存储 算法 Java
Java常用的数据结构
【10月更文挑战第3天】 在 Java 中,常用的数据结构包括数组、链表、栈、队列、树、图、哈希表和集合。每种数据结构都有其特点和适用场景,如数组适用于快速访问,链表适合频繁插入和删除,栈用于实现后进先出,队列用于先进先出,树和图用于复杂关系的表示和查找,哈希表提供高效的查找性能,集合用于存储不重复的元素。合理选择和组合使用这些数据结构,可以显著提升程序的性能和效率。
|
1月前
|
存储 Java
数据结构第二篇【关于java线性表(顺序表)的基本操作】
数据结构第二篇【关于java线性表(顺序表)的基本操作】
31 6
下一篇
无影云桌面