您的位置:首页 > 理论基础 > 数据结构算法

【Java数据结构】排序

2016-01-05 10:43 567 查看
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
;
}

//选择排序
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
;
}

//按学号排序
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: