Java数据结构与算法(第七章高级排序2)

划    分

划分数据就是把数据分为两组,使所有关键字大于特定值的数据项在一组,是所有关键字小于特定值的数据项在另一组。

package com.gaojipaixu.partition;

public class Arraypar{
    private long[] theArray;
    private int nElems;
    
    public Arraypar(int max){
        theArray = new long[max];
        nElems = 0;
    }
    
    public void insert(long value){
        theArray[nElems] = value;
        nElems++;
    }
    
    public int size(){
        return nElems;
    }
    
    public void display(){
        System.out.print("A=");
        for (int i = 0; i < nElems; i++) {
            System.out.print(theArray[i]+" ");
        }
        System.out.println("");
    }
    
    public int partitionIt(int left,int right,long pivot){
        int leftPtr = left-1;
        int rightPtr = right+1;
        while(true){
            while(leftPtr<right && 
                theArray[++leftPtr]<pivot)
                ;
            while(rightPtr>left && 
                theArray[--rightPtr]>pivot)
                ;
            if(leftPtr >= rightPtr)
                break;
            else{
                long temp ;
                temp = theArray[leftPtr];
                theArray[leftPtr] = theArray[rightPtr];
                theArray[rightPtr] = temp;
            }
        }
        return leftPtr;
    }
}
	public static void main(String[] args) {
		int maxSize = 16;
		Arraypar arr ;
		arr = new Arraypar(maxSize);
		for (int i = 0; i < maxSize; i++) {
			long n = (int)(java.lang.Math.random()*199);
			arr.insert(n);
		}
		arr.display();

		long pivot = 99;

		System.out.println("Pivot is "+pivot);
		int size = arr.size();

		int partDex = arr.partitionIt(0, size-1, pivot);

		System.out.println(",Partition is at index "+partDex);
		arr.display();

	}

//输出:
A=170 142 81 128 131 39 16 186 84 35 46 195 174 114 144 103 
Pivot is 99
,Partition is at index 6
A=46 35 81 84 16 39 131 186 128 142 170 195 174 114 144 103

可以看出划分是成功的:前6个数字都比枢纽99小;后8个数字则都大于枢纽。

注意划分的过程不一定要像这个例子一样把数组划分成大小相同的两半;这取决于枢纽及数据关键字的值。有可能一组中数据项个数多于另一组的数据项个数。

划分算法

划分算法由两个指针开始工作,两个指针分别指向数组的两头。(这里使用“指针”这个词是指示数组数据项的,而不是C++中所说的指针。)在左边的指针,leftPtr,向右移动,而在右边的指针,rightPtr,向左移动。

实际上,leftPtr初始化是时在第一个数据项的左边一位,rightPtr是在最后一个数据项的右边一位,这是因为在它们工作之前,它们都要分别的加一和减一。

停止和交换

当leftPtr遇到比枢纽小的数据项时,它继续右移,因为这个数据项的位置已经处在数组的正确一边了。但是,当遇到比枢纽大的数据项时,它就停下来,类似的,当rightPrt遇到大于枢纽的数据项时,它继续左移但是当发现比枢纽小的数据项时,它也停下来。当两个内层的while循环,第一个应用leftPtr,第二个应用于rightPrt,控制这个扫描过程。因为指针退出了while循环,所以它停止移动。下面是一段扫描不在适当位置上的数据项的简化代码:

while(theArray[++leftPtr] < pivot) //find bigger item
    ;    //(nop)
while(theArray[--right]>pivot)   //find smaller item
    ;    //(nop)
swap(lefgPtr,rightPtr);            //swap elements

第一个while循环在发现比枢纽大的数据项时退出;第二个循环在发现小的数据项时退出。当这两个循环都退出之后,leftPtr和rightPrt都指着在数组的错误一方位置上的数据项,所以交换着两个数据项。

256

时间: 2024-10-22 02:05:48

Java数据结构与算法(第七章高级排序2)的相关文章

Java数据结构和算法(九)——高级排序

春晚好看吗?不存在的!!! 在Java数据结构和算法(三)——冒泡.选择.插入排序算法中我们介绍了三种简单的排序算法,它们的时间复杂度大O表示法都是O(N2),如果数据量少,我们还能忍受,但是数据量大,那么这三种简单的排序所需要的时间则是我们所不能接受的.接着我们在讲解递归 的时候,介绍了归并排序,归并排序需要O(NlogN),这比简单排序要快了很多,但是归并排序有个缺点,它需要的空间是原始数组空间的两倍,当我们需要排序的数据占据了整个内存的一半以上的空间,那么是不能使用归并排序的. 本篇博客将

Java数据结构和算法之数组与简单排序

一.数组于简单排序 数组 数组(array)是相同类型变量的集合,可以使用共同的名字引用它.数组可被定义为任何类型,可以是一维或多维.数组中的一个特别要素是通过下标来访问它.数组提供了一种将有联系的信息分组的便利方法. 一维数组 一维数组(one‐dimensional array )实质上是相同类型变量列表.要创建一个数组,你必须首先定义数组变量所需的类型.通用的一维数组的声明格式是: type var‐name[ ]; 获得一个数组需要2步: 第一步,你必须定义变量所需的类型. 第二步,你必

Java数据结构与算法(第一章综述)

数据结构和算法能起到什么作用? 数据结构是对在计算机内存中(有时在磁盘中)的数据的一种安排.数据结果包括数组.链表.栈.二叉树.哈希表等等.算法对这些结构中的数据进行各种处理,例如,查找一条特殊的数据项或对数据进行排序. 可用于下面三类情况: 现实数据存储 程序员的工具 建模 数据结构的特性: 数据结构 优点 缺点 数组 插入快,如果知道下标,可以非常快地存取 查找慢,删除慢,大小固定 有序数组 比无序的数组查找快 删除和插入慢,大小固定 栈 提供后进先出的方式存取 存取其他项很慢 队列 提供先

Java数据结构与算法(第七章高级排序1)

希尔排序 希尔排序是计算机科学家Donald L.Shell 而得名,他在1959年发现了希尔排序算法.希尔排序基于插入排序,但是增加了一个新的特性,大大提高了插入排序的执行效率. 插入排序:复制的次数太多 由于希尔排序是基于插入排序的,所以需要回顾下"插入排除".在插入排除执行的一半的时候,标记符左边这部分数据项都是排过序的(这些数据之间是有序的),而记右边的数据项没有排过序.这个算法取出标记符所指的数据项,把它存储在一个临时的变量.接着,从刚刚被移除的数据项的左边第一个单元看是,每

Java数据结构与算法(第二章数组)

数组是应用最广泛的数据存储结构.它被植入到大部分编程语言中. Java中数组的基础知识     创建数组 在Java中把它们当作对象来对待,因此在创建数组是必须使用new操作符:     int[] intArray;            //defines a reference to an array     ingArray = new int[100];    //creates the array, and                                  //set

数据结构与算法第12章 高级数据结构及其实现

这一章要讲的数据结构基本以实用为主. 12.1 自顶而下的伸展树 一些定义 展开:对于树的操作,叶结点X被插入之后,经过旋转使X成为新的树根. 摊还时间:在摊还分析中的一个概念,就是求一个操作的所有情况的平均时间.和O()的时间不同,后者体现的是最糟糕的情况下程序完成所要花费的时间. P345之中,还有一些内容不是很明白,比如图12.1之中,为什么旋转之后树之间是断开的.我不是很清楚这是怎么回事.

Java数据结构和算法(七)——链表

前面博客我们在讲解数组中,知道数组作为数据存储结构有一定的缺陷.在无序数组中,搜索性能差,在有序数组中,插入效率又很低,而且这两种数组的删除效率都很低,并且数组在创建后,其大小是固定了,设置的过大会造成内存的浪费,过小又不能满足数据量的存储. 本篇博客我们将讲解一种新型的数据结构——链表.我们知道数组是一种通用的数据结构,能用来实现栈.队列等很多数据结构.而链表也是一种使用广泛的通用数据结构,它也可以用来作为实现栈.队列等数据结构的基础,基本上除非需要频繁的通过下标来随机访问各个数据,否则很多使

java数据结构和算法-----第四章

栈和队列 栈(后进先出) 栈,只允许访问一个数据项:即最后插入的数据项. 栈可以用来检查括号的匹配问题和解析数学表达式,类似于在编译原理中的使用. 该图片的操作实际上归纳起来:1.读到左分隔符入栈,2.读到右分隔符就和从栈顶弹出来的左分割符匹配,匹配成功,就正常进行. 3.读到一般的字母字符,就过滤掉.栈的入栈和出栈的时间复杂度都是O(1) 队列(先进先出) 队列的主要有以下几种方法:insert(),remove(),peek(),isFull(),isEmpty()和size()

数据结构与算法第7章:排序

这一章主要讨论整数的排序. 7.2 插入排序 插入算法是学习排序的最基本的算法.非常简单好理解的算法,大意是,位置X上面的元素前面的元素都是排过序的.当这个元素需要排序时,在前面之中,为X上面的元素找到一个合适的位置. void InsertionSort(int* a, int n) { int i, j; int temp;//用于替换的元素 for (i = 1; i < n; ++i) { temp = a[i]; for (j = i; j > 0 && a[j -