《Java数据结构和算法》第二版 Robert lafore 编程作业 第三章

《Java数据结构和算法》第二版 Robert lafore  编程作业 第三章

/*
  	3.1 bubbleSort.java程序(清单3.1)和BubbleSort专题applet中,in索引变量都是从左到
  		右移动的,直到找到最大数据项并把它移动到右边的out变量外。修改bubbleSort()方法,
  		使它成为双向移动的。这样,in索引先像以前一样,将最大的数据项从左移到右,当它到
  		达out变量位置时,它掉头并把最小的数据项从右移到左。需要两个外部索引变量,一个在
  		右边(以前的out变量),另一个在左边。
  	3.2	在isertSort.java程序(清单3.3)中给ArrayIns类加一个median()方法.这个方法将返回
  		数组的中间值.(回忆一下,数组中一半数据项比中间值大,一半数据项比中间值小。)
 	3.3	在insertSort.java程序(清单3.3)中增加一个名为noDups()的方法,这个方法从已经有
 		序的数组中删掉重复的数据项而不破坏有序性。(可以用insertionSort()方法对数据排序,
 		或者也可以简单地用main()方法将数据有序地插入到表中。)一种解决方法是每发现一个重
 		复的数据,就从这个位置开始到数组结尾都向前移动一个位置,但这样就导致消耗很长的
 		O(N2)的时间级,起码在有很多重复数据项的情况下是这样的。在设计的算法中,不论有多
 		少重复数据,要确保数据项最多只能移动一次。这样算法只消耗O(N)数量级的时间。
 	3.4  还有一种简单排序算法是奇偶排序。它的思路是在数组中重复两趟扫描。第一趟扫描选择所有
 		的数据项对,a[j]和a[j+1],j是奇数(j=1,3,5,……)。如果它们的关键字的值次序颠倒,就交
 		换它们。第二趟扫描对所有的偶数数据项进行同样的操作(j=2,4,6,……)。重复进行这样两趟
 		的排序直到数组全部有序。用oddEvenSort()方法替换bubbleSort.java程序(清单3.1)中的
 		bubbleSort()方法。确保它可以在不同数据量的排序中运行,还需要算出两趟扫描的次数。奇
 		偶排序实际上在多处理器环境中很有用,处理器可以分别同时处理每一个奇数对,然后又同时
 		处理偶数对。因为奇数对是彼此独立的,每一对都可以用不同的处理器比较和交换。这样可以非
 		常快速地排序。
 	3.5	修改insertSort.java程序(清单3.3)中的insertionSort()方法,使它可以计算排序过
 		程中复制和比较的次数并显示出总数。为计算比较的次数,要把内层while循环的两个条件分开。
 		用这个程序测量各种数量的逆序数据排序的复制和比较次数。结果满足O(N2)吗?与已经基本有
 		序的数据(仅有很少的数据无序)的情况一样吗?从对基本有序数据排序的表现中可得出关于这
 		个算法效率的什么结论?
 	3.6	有一个有趣的方法用来删除数组中相同的数据项。插入排序算法中用一个循环嵌套算法,将
 		数组中的每一个数据项与其他数据项一一比较。如果要删除相同的数据项,可以这样做(参见第
 		2章第2.6小节)。修改insertSort.java中的insertionSort()方法,使它可以在排序过程中
 		删除相同的数据项。方法如下:当找到一个重复数据项的时候,通常用一个小于任何值的关键值
 		来改写这个相同数据项(如果所有值都是正数,则可取-1)。于是,一般的插入排序算法就会像
 		处理其他数据项一样,来处理这个修改了关键值的数据项,把它移到下标为0的位置。从现在开
 		始,算法可以忽略这个数据项。下一个相同的数据项将被移到下标为1的位置,依此类推。排序
 		完成后,所有相同的数据项(现在关键值为-1)都在数组的开头部分。可以改变数组的容量并
 		把需要的数据前移动数组下标为0的位置。
 */
package chap03;

// bubbleSort.java
// demonstrates bubble sort
// to run this program: C>java BubbleSortApp

class ArrayBub {
	private long[] a; // ref to array a
	private int nElems; // number of data items

	// --------------------------------------------------------------

	public ArrayBub(int max) // constructor
	{
		a = new long[max]; // create the array
		nElems = 0; // no items yet
	}

	// --------------------------------------------------------------
	public void insert(long value) // put element into array
	{
		a[nElems] = value; // insert it
		nElems++; // increment size
	}

	// --------------------------------------------------------------
	public void display() // displays array contents
	{
		for (int j = 0; j < nElems; j++)
			// for each element,
			System.out.print(a[j] + " "); // display it
		System.out.println("");
	}

	// --------------------------------------------------------------
	public void bubbleSort() {
		int out, in;
		for (out = nElems - 1; out > 0; out--)
			// outer loop (backward) //这里必须是 out > 0 如果是 > 1的话,4321 会排成 2134
			for (in = 0; in < out; in++)
				// inner loop (forward)
				if (a[in] > a[in + 1]) // out of order?
					swap(in, in + 1); // swap them
	} // end bubbleSort()

	// --------------------------------------------------------------

	// ==============================================================
	// 编程作业3.1 P78(97)
	public void bubbleSort1() {
		int leftout = 0, rightout = nElems - 1, in; // leftout,rightout为左右两端指针
		for (; rightout > leftout; rightout--, leftout++) {
			for (in = leftout + 1; in < rightout; in++)
				if (a[in] > a[in + 1])
					swap(in, in + 1);
			for (in = rightout - 1; in > leftout; in--)
				if (a[in] < a[in - 1])
					swap(in, in - 1);
		}
	}

	// ==============================================================
	// 编程作业3.4 P79(98)

	// 奇偶排序的过程如下
	// 初始序列 4 3 2 1
	// 第1次
	// i为偶数比较 (4,3)和(2,1)对
	// 结果为 3 4 1 2
	// i为奇数比较 (4,1)对
	// 结果为 3 1 4 2
	// 第2次
	// i为偶数比较 (3,1)和(4,2)对
	// 结果为1 3 2 4
	// i为奇数比较 (3,2)对
	// 结果为1 2 3 4
	// 第3次
	// i为偶数比较 (1,2)和(3,4)对
	// 结果为1 2 3 4
	// i为奇数比较(2,3)
	// 结果为1 2 3 4
	// 此次比较没有交换,所以排序结束

	public void oddEvenSort() {
		boolean change = true;
		while (change) {// 当不再有交换时,排序完成
			change = false;
			for (int i = 0; i < nElems - 1; i += 2) { // i为偶数
				if (a[i] > a[i + 1]) {
					swap(i, i + 1);
					change = true;
				}
			}
			for (int i = 1; i < nElems - 1; i += 2) { // i为奇数
				if (a[i] > a[i + 1]) {
					swap(i, i + 1);
					change = true;
				}
			}
		}
	}

	// ==============================================================
	// 使用一个独立的方法不一定好,因为方法调用会增加一些额外的消耗。自己的程序里将交
	// 换操作这段代码直接放到程序中。
	private void swap(int one, int two) {
		long temp = a[one];
		a[one] = a[two];
		a[two] = temp;
	}
	// --------------------------------------------------------------
} // end class ArrayBub
// //

public class BubbleSortApp {
	public static void main(String[] args) {
		int maxSize = 100; // array size
		ArrayBub arr; // reference to array
		arr = new ArrayBub(maxSize); // create the array

		arr.insert(77); // insert 10 items
		arr.insert(99);
		arr.insert(44);
		arr.insert(55);
		arr.insert(22);
		arr.insert(88);
		arr.insert(11);
		arr.insert(00);
		arr.insert(66);
		arr.insert(33);

		arr.display(); // display items
		arr.bubbleSort(); // bubble sort them
		arr.display(); // display them again

		// ======================================
		// 编程作业3.1 P78(97)
		arr = new ArrayBub(maxSize); // create the array
		arr.insert(4);
		arr.insert(3);
		arr.insert(2);
		arr.insert(1);
		arr.display(); // display items
		arr.bubbleSort1(); // bubble sort them
		arr.display(); // display them again
		// ======================================
		// //编程作业3.4 P79(98)
		ArrayBub arr1 = new ArrayBub(maxSize);
		arr1.insert(8);
		arr1.insert(7);
		arr1.insert(6);
		arr1.insert(5);
		arr1.display();
		arr1.oddEvenSort(); // 奇偶排序
		arr1.display();
		// ======================================
	} // end main()
} // end class BubbleSortApp
// //
package chap03;

// insertSort.java
// demonstrates insertion sort
// to run this program: C>java InsertSortApp
//--------------------------------------------------------------
class ArrayIns {
	private long[] a; // ref to array a
	private int nElems; // number of data items

	// --------------------------------------------------------------

	public ArrayIns(int max) // constructor
	{
		a = new long[max]; // create the array
		nElems = 0; // no items yet
	}

	// --------------------------------------------------------------
	public void insert(long value) // put element into array
	{
		a[nElems] = value; // insert it
		nElems++; // increment size
	}

	// --------------------------------------------------------------
	public void display() // displays array contents
	{
		for (int j = 0; j < nElems; j++)
			// for each element,
			System.out.print(a[j] + " "); // display it
		System.out.println("");
	}

	// --------------------------------------------------------------
	public void insertionSort() {
		int in, out;
		for (out = 1; out < nElems; out++) // out is dividing line
		{
			long temp = a[out]; // remove marked item
			in = out; // start shifts at out
			while (in > 0 && a[in - 1] >= temp) // until one is smaller,//这里 a[in-1]= temp的时候,可以不用移动,可以改成 a[in-1] > temp
			{
				a[in] = a[in - 1]; // shift item to right
				--in; // go left one position
			}
			a[in] = temp; // insert marked item
		} // end for
	} // end insertionSort()

	// --------------------------------------------------------------

	// ==========================================================
	// 编程作业3.5 P79(98)
	public int insertionSort1() {
		int in, out;
		int compare = 0; // 比较次数
		int copy = 0; // 复制次数
		for (out = 1; out < nElems; out++) // out is dividing line
		{
			long temp = a[out]; // remove marked item
			in = out; // start shifts at out
			while (in > 0) // until one is smaller,
			{
				if (a[in - 1] > temp) {
					a[in] = a[in - 1]; // shift item to right
					--in; // go left one position
					compare++;
					copy++;
				} else {
					compare++;
					break;
				}
			}
			a[in] = temp; // insert marked item
		} // end for
		return compare + copy;
	} // end insertionSort()

	// ==========================================================
	// 编程作业3.6 P79(98)
	public void insertionSort2() {
		int in, out, count = 0;
		for (out = 1; out < nElems; out++) // out is dividing line
		{
			long temp = a[out]; // remove marked item
			in = out; // start shifts at out
			while (in > 0 && a[in - 1] >= temp && a[in - 1] != -1) // until one is smaller,
			{
				if (a[in - 1] == temp) {
					temp = -1;
					count++;
				}
				a[in] = a[in - 1]; // shift item to right
				--in; // go left one position
			}
			a[in] = temp; // insert marked item
		} // end for
		nElems -= count;
		for (int i = 0; i < nElems; i++) {
			a[i] = a[i + count]; // 把排好序的元素向前移动count个位置
		}
	} // end insertionSort()

	// ===========================================================
	// 编程作业3.2 P78(97) //数组的中间值,到底是位置上的中间,还是大小上的中间?
	public long median() {
		this.insertionSort(); // 先排序,再取中间值 //这个中间值是大小上的中间值.
		return a[nElems / 2];
	}

	// ===========================================================
	// 编程作业3.3 P78(97)
	// 方法一
	public void noDups() {
		this.insertionSort();// 先排序
		int holenumber = 0;
		final int FLAG = -1; // 标记为空,假设用户不会输入负数
		for (int i = 0; i < nElems; i++) { // 把重复的都标记出来
			for (int j = i + 1; j < nElems; j++) {// 从i+1开始
				if (a[i] == a[j] && a[j] != FLAG) {
					a[j] = FLAG;
					holenumber++;
				}
			}
		}
		int firsthole = -1; // 第一个空位的索引
		for (int i = 0; i < nElems; i++) {
			if (a[i] == FLAG && firsthole == -1) { // 遇到第一个空位时,则这个空位为firsthole
				firsthole = i;
			} else if (a[i] != FLAG && firsthole != -1) {// 当有空位时,遇到一个非空值,就把这个非空值复制到firsthole的位置
				a[firsthole++] = a[i]; // 同时,firthole++,空位往后移一位
			}
		}
		nElems -= holenumber;
	}

	// 方法二
	public void noDups1() {
		this.insertionSort();// 先排序
		long NIL = Long.MIN_VALUE; // 标志位
		for (int i = 0; i < nElems - 1; i++) {
			if (a[i] == a[i + 1]) {
				a[i] = NIL; // NIL为标志位,相当于楼主的-1,使用的是Long.MIN_VALUE
			}
		}
		int order = 0;
		for (int temp = 0; temp < nElems;) {
			if (a[temp] != NIL) {// 因为a[0]不可能等于NIL所以才可以用这种方法
				if (temp > order) {
					a[order] = a[temp];
				}
				temp++;
				order++;
			} else
				temp++;
		}
		nElems = order;
	}
	// ===========================================================
} // end class ArrayIns
// //

public class InsertSortApp {
	public static void main(String[] args) {
		int maxSize = 100; // array size
		ArrayIns arr; // reference to array
		arr = new ArrayIns(maxSize); // create the array

		arr.insert(77); // insert 10 items
		arr.insert(99);
		arr.insert(44);
		arr.insert(55);
		arr.insert(22);
		arr.insert(88);
		arr.insert(11);
		arr.insert(00);
		arr.insert(66);
		arr.insert(33);
		arr.display(); // display items
		arr.insertionSort(); // insertion-sort them

		arr.display(); // display them again

		// ======================================
		// 插入4321
		arr = new ArrayIns(maxSize); // create the array
		arr.insert(4);
		arr.insert(3);
		arr.insert(2);
		arr.insert(1);
		arr.display(); // display items
		arr.insertionSort(); // insertion-sort them
		arr.display(); // display them again

		// ======================================
		// 编程作业3.3 P78(97)
		arr = new ArrayIns(maxSize); // create the array
		arr.insert(2);
		arr.insert(3);
		arr.insert(4);
		arr.insert(3);
		arr.insert(3);
		arr.insert(1);
		arr.insert(2);
		arr.insert(1);
		arr.insert(1);
		arr.insert(1);
		System.out.println("插入重复值后:");
		arr.display();
		arr.noDups();
		System.out.println("删除重复值后:");
		arr.display();

		// ======================================
		// 编程作业3.5 P79(98)
		arr = new ArrayIns(maxSize); // create the array
		int count;
		for (int i = 19; i >= 0; i--) {// 初始化为逆序数组
			arr.insert(i);
		}
		arr.insert(19);
		arr.insert(9);
		arr.insert(0);
		arr.display();
		count = arr.insertionSort1();
		arr.display();
		System.out.println("逆序数组比较复制总数:" + count); // 满足O(N^2)

		arr = new ArrayIns(maxSize); // create the array
		for (int i = 0; i <= 19; i++) {// 初始化为顺序数组
			arr.insert(i);
		}
		arr.insert(19);
		arr.insert(9);
		arr.insert(0);
		arr.display();
		count = arr.insertionSort1();
		arr.display();
		System.out.println("顺序数组比较复制总数:" + count); // 满足O(N)
		// ======================================
		// 编程作业3.6 P79(98)
		arr = new ArrayIns(maxSize); // create the array
		arr.insert(2);
		arr.insert(3);
		arr.insert(4);
		arr.insert(3);
		arr.insert(3);
		arr.insert(1);
		arr.insert(2);
		arr.insert(1);
		arr.insert(1);
		arr.insert(1);
		System.out.println("插入重复值后:");
		arr.display();
		arr.insertionSort2();
		System.out.println("删除重复值后:");
		arr.display();
		// ======================================

	} // end main()
} // end class InsertSortApp
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值