内排序若干Java实现
来源:互联网 发布:linux nginx php7配置 编辑:程序博客网 时间:2024/06/05 04:59
一:插入排序:
1:直接插入排序:
•思想:每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的字序列的合适位置,直到全部插入排序完为止。
•关键问题:在前面已经排好序的序列中找到合适的插入位置。
在编程上:
1:遍历整个数组:
2:在每次取到某个元素之后,然后将该元素插入前面已经排好的数组中,然后将大于该元素的数据整体后移一个,因此后面的值会被覆盖,首先要保存当前待排序的元素,然后后移之后将元素写入到应该插入的位置.
int[] a={12,34,45,67,25,79,123,11,9,4,2345};
for (inti = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
int[]b =newint[a.length];
for(inti=0;i<a.length;i++){
inttemp=a[i];
intj;
for(j=i-1;j>=0;j--){
if(a[j]>temp){
a[j+1]=a[j];
}else{
break;
}
}
a[j+1]=temp;
}
System.out.println();
for (inti = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
2:二分法插入排序(按二分法找到合适位置插入)
1、 基本思想:二分法插入排序的思想和直接插入一样,只是找合适的插入位置的方式不同,这里是按二分法找到合适的位置,可以减少比较的次数。
2、 在程序上:也是保存当前待排序的元素,然后利用二分法去搜索已经排好的元素,然后去找到一个该插入的值,然后整体后移,然后更新该值.也是直接插入排序的一种变种.
int[] a={12,34,45,67,25,79,123,11,9,4,2345};
for (inti = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
int[]b =newint[a.length];
for(inti=0;i<a.length;i++){
inttemp=a[i];
intj;
intleft=0;
intright=i-1;
intmid=0;
while(left<=right){
if(temp>a[mid]){
left=mid+1;
}else{
right=left-1;
}
}
// 找到该插入的位置后,位置后的数据整体后移动,然后插入
for (j = i-1; j >= left; j--) {
a[j+1] =a[j];
}
if(left !=i){
a[left] =temp;
}
}
System.out.println();
for (inti = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
3:希尔排序:
1、 基本思想:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。该方法实质上是一种分组插入方法。
2、 编程上:也是直接插入排序的变种,只是按照偏移量d将数据分为小组,每个组的成员为i,i+d,i+2d....,在分组内用直接插入排序,然后将偏移量d减小,重新再新的小组内排序,知道d=1,此时就是直接插入排序,不过已经整改数据大致应该已经排好,此时虽然d=1,但是直接插入排序的性能已经是接近最好,比较次数为o(n).
编程实现: int[]a={12,34,45,67,25,79,123,11,9,4,2345};
for (inti = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
int d=a.length;
while(true){
d=d/2;
for(intx=0;x<d;x++){
for(inti=x+d;i<a.length;i=i+d){
inttemp=a[i];
intj;
for(j=i-d;j>0;j=j-d){
if(a[j]>temp){
a[j+d]=a[j];
}else{
break;
}
}
a[j+d]=temp;
}
}
if(d==1){
break;
}
}
System.out.println();
System.out.println("排序之后:");
for (inti = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
二:选择排序:
•思想:每趟从待排序的记录序列中选择关键字最小的记录放置到已排序表的最前位置,直到全部排完。
•关键问题:在剩余的待排序记录序列中找到最小关键码记录。
•方法:
–直接选择排序
–堆排序
①简单的选择排序
1、 基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。
编程上:要注意保留index和被排序的元素,要彼此交换.位置 int[]a={12,34,45,67,25,79,123,11,9,4,2345};
for (inti = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
for(inti=0;i<a.length;i++){
inttemp=a[i];
intindex=i;
for(intj=i;j<a.length;j++){
if(a[j]<temp){
temp=a[j];
index =j;
}
}
a[index]=a[i];
a[i]=temp;
System.out.println();
for (intm = 0; m < a.length; m++) {
System.out.print(a[m]+" ");
}
}
②堆排序
1、基本思想:
堆排序是一种树形选择排序,是对直接选择排序的有效改进。
堆的定义下:具有n个元素的序列(h1,h2,...,hn),当且仅当满足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)时称之为堆。在这里只讨论满足前者条件的堆。由堆的定义可以看出,堆顶元素(即第一个元素)必为最大项(大顶堆)。完全二叉树可以很直观地表示堆的结构。堆顶为根,其它为左子树、右子树。
思想:初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,使之成为一个堆,这时堆的根节点的数最大。然后将根节点与堆的最后一个节点交换。然后对前面(n-1)个数重新调整使之成为堆。依此类推,直到只有两个节点的堆,并对它们作交换,最后得到有n个节点的有序序列。从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。所以堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数:主要是保证父节点的值大于左右两个子节点的值,然后还需要遍历
public staticvoidmain(String[] args){
// TODO Auto-generated method stub
int[]a={49,38,65,97,76,13,27,49,78,34,12,64};
int arrayLength=a.length;
//循环建堆
for(inti=0;i<arrayLength-1;i++){
//建堆
buildMaxHeap(a,arrayLength-1-i);
//交换堆顶和最后一个元素
swap(a,0,arrayLength-1-i);
System.out.println(Arrays.toString(a));
}
}
public static void swap(int[]data,inti,intj){
int temp =data[i];
data[i]=data[j];
data[j]=temp;
}
/*
*
* 每次重建前N-1个元素的堆
*/
//对data数组从0到lastIndex建大顶堆
public static void buildMaxHeap(int[]data, intlastIndex){
//从lastIndex处节点(最后一个节点)的父节点开始
for(inti=(lastIndex-1)/2;i>=0;i--){
//k保存正在判断的节点
intk=i;
//如果当前k节点的子节点存在
while(k*2+1<=lastIndex){
//k节点的左子节点的索引
intbiggerIndex=2*k+1;
//如果biggerIndex小于lastIndex,即biggerIndex+1代表的k节点的右子节点存在
if(biggerIndex<lastIndex){
//若果右子节点的值较大
if(data[biggerIndex]<data[biggerIndex+1]){
//biggerIndex总是记录较大子节点的索引
biggerIndex++;
}
}
//如果k节点的值小于其较大的子节点的值
if(data[k]<data[biggerIndex]){
//交换他们
swap(data,k,biggerIndex);
//将biggerIndex赋予k,开始while循环的下一次循环,重新保证k节点的值大于其左右子节点的值
k=biggerIndex;
}else{
break;
}
}
}
}
三:交换排序
① 冒泡排序
② 基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换
③ 编程思想:每次循环一次,将最大的数交换到最后的位置,第一次选择一个最大的数到最后,第二次选择一个到倒数第二个.通过将彼此顺序交换,将最大数换到最后,选择排序是每次选择最大的一个数排到最后.不交换
④ int[]a={12,34,45,67,25,79,123,11,9,4,2345};
for (inti = 0;i < a.length;i++) {
System.out.print(a[i]+" ");
}
//冒泡排序
for (inti = 0; i < a.length; i++) {
for(intj = 0; j<a.length-i-1;j++){
//这里-i主要是每遍历一次都把最大的i个数沉到最底下去了,没有必要再替换了
if(a[j]>a[j+1]){
inttemp = a[j];
a[j] =a[j+1];
a[j+1] =temp;
}
}
}
System.out.println();
for (inti = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
②快速排序
1、基本思想:选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。
1、重点在于找到基准元素,应该处的位置,然后将元素分为两部分,将小于基准元素的靠前,大于基准元素的靠后,分别从左右两端开始搜索,每次替换一个元素,在程序中以第一个元素为基准,分别从左右两端搜索,比较并且交换,最后得到基准元素位置. public staticvoidmain(String[] args){
// TODO Auto-generated method stub
int[]a={49,38,65,97,76,13,27,49,78,34,12,64,1,8};
System.out.println("排序之前:");
for (inti = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
//快速排序
quickSort(a,0,a.length-1);
System.out.println();
System.out.println("排序之后:");
for (inti = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
}
public static void quickSort(int[]a,intlow,inthigh){
if(low<high){
intmiddle=getMiddle(a,low,high);
quickSort(a,low,middle);
quickSort(a,middle+1,high);
}
}
public static int getMiddle(int[]a,intlow,inthigh){
int tmp =a[low];// 基准元素
while(low<high){
// 找到比基准元素小的元素
while(low<high&&a[high] >=tmp){
high--;
}
a[low]=a[high];
while(low<high&&a[low]<=tmp){
low++;
}
a[high]=a[low];
}
a[low]=tmp;
returnlow;
}
四:归并排序:
1、 基本思想:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
关键是递归思想 public static void main(String[] args) {
// TODO Auto-generated method stub
int[]a={49,38,65,97,76,13,27,49,78,34,12,64,1,8};
System.out.println("排序之前:");
for (inti = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
//快速排序
sort(a,0,a.length-1);
System.out.println();
System.out.println("排序之后:");
for (inti = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
}
public static void sort(int[]a,intleft,intright){
if(left<right){
intmiddle=(left+right)/2;
sort(a,left,middle);
sort(a,middle+1,right);
merge(a,left,middle,right);
}
}
public static void merge(int[]a,intleft,intmiddle,intright){
int[]tmpArr=newint[a.length];
int mid=middle+1;//右边的起始位置
int tmp=left;
int third=left;
//从两个数组中选取较小的数放入中间数组
while(left<=middle &&mid <=right){
if(a[left]<a[mid]){
tmpArr[third++]=a[left++];
}else{
tmpArr[third++]=a[mid++];
}
}
//将剩余的部分放入中间数组
while(left <=middle){
tmpArr[third++]=a[left++];
}
while(mid <=right){
tmpArr[third++]=a[mid++];
}
//将中间数组复制回原数组
while(tmp<=right){
a[tmp] =tmpArr[tmp++];
}
}
- 内排序若干Java实现
- 内排序Java实现
- java实现字符串内排序
- 内排序的java实现
- 常见内排序算法的java实现
- JAVA实现八大内排序算法
- 八大常见内排序java实现
- 内排序算法的java实现---直接选择排序
- 内排序算法的java实现---冒泡排序
- 内排序算法的java实现---快速排序
- dataTable内实现排序
- dataTable内实现排序
- JavaScript 实现内排序算法
- Java内排序算法一
- Java内排序算法二
- java实现内部类
- Java实现内部类
- JAVA实现对某一时间(hh:mm)增加若干分钟
- hdu 5493 Queue(逆序对,线段树)
- 旋转卡壳大解析
- 简单的javascript学习03
- Loadrunner 测试网页下载文件的脚本实例
- linux开机启动详细流程
- 内排序若干Java实现
- CSS3属性(3):nth-child()属性
- To Be A Better Learner
- thinking in java test4.5练习(6)(7)
- {模版}KMP字符串匹配
- memcached 安装
- undefined reference to `std::cout'等错误
- 【USACO题库】2.4.4 Bessie Come Home回家
- Qt---Label