数据结构中一些示例的代码实现

转载出处

本文作者: HuaShan
本文链接: http://denghs.com/2018/02/26/data_struct/

科学的研究方法(摘录至文明之光一书)

  1. 不盲从,不接受任何自己不清楚的真理。不管有什么权威的结论,只要没有经过自己的研究,都可以怀疑。
  2. 对于复杂的问题,尽量分解为多个简单的小问题来研究,一个一个地分开解决。
  3. 解决这些小问题时,应该按照先易后难的次序,逐步解决。
  4. 解决每个小问题之后,再综合起来。看看是否彻底解决了原来的问题。

内存溢出和内存泄露

内存溢出

内存溢出主要是指,要装的数据要超过容器本身了,这是则会导致溢出。类似与生活中的水桶、杯子等,容量是有限的,所以不能进行无限的填装。像Java中的OOM,就属于内存溢出。因为Java中GC的存在,所以并不会发生内存泄露。

内存泄露

上一章用到C语言制造链表,对于链表中结点的删除操作,会有一个free()函数的调用。free()函数的作用是释放内存空间。**所谓的释放内存空间,是指把对内存地址的操作权限移交给操作系统。**如果没有做free()这个操作,删除该结点时,会导致该结点在已经无法找到了,但却还拥有控制权限。操作系统在分配内存时,会认为当前内存地址有人还在使用,就不会分配给其他的应用程序,从而会导致内存空间,越用越少。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WHWhn3mz-1591368532694)(http://orxmumro7.bkt.clouddn.com/18-4-19/47041275.jpg)]

排序

排序的稳定性

所谓稳定性是指,如果序列中两个数据元素相等,即r[i]==r[j],排序前r[i]在r[j]前,排序后r[i]仍然在r[j]前,则这个排序算法是稳定的,反之是不稳定的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w35yTACA-1591368532697)(http://orxmumro7.bkt.clouddn.com/18-4-24/48751992.jpg)]

选择排序

其基本思想是从待排序的无序区中找出最小的元素,将该元素与该区中的第一个元素交换位置。该排序算法是不稳定的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UUh208FD-1591368532699)(http://orxmumro7.bkt.clouddn.com/18-4-24/50811202.jpg)]

package datastructure.part.sort;

import java.util.Arrays;

/**
 * @description
 * @author Denghs
 * @version 1.0,2018年2月27日 上午9:27:32
 * @remark 
 * 选择排序:每一次在无序的序列中选出关键字最小的记录,依次存放在已排好序的记录序列最后。
 * 原始 数据:5 4 9 87 1 2 14 26
 * 	第一趟      1 5 4 9 87 2 14 26
 *  第二趟      1 2 5 4 9 87 14 26
 *  第三趟      1 2 4 5 9 87 14 26
 *  第四趟      1 2 4 5 9 87 14 26
 *  第五趟      1 2 4 5 9 87 14 26
 *  第六趟      1 2 4 5 9 14 87 26
 *  第七趟      1 2 4 5 9 14 26 87
 */
public class ChooseSort {

	public static void main(String[] args) {
		//统计运行次数
		int count = 0;
		int[] array = { 5, 4, 9, 87, 1, 2, 14, 26 };
		chooseSort(array, count);
	}
	
	/**
	 * 选择排序
	 * @param array
	 * @param count
	 */
	public static void chooseSort(int[] array, int count) {
		for (int i = 0; i < array.length; i++) {
			for (int j = i + 1; j < array.length; j++) {
				if(array[j] < array[i]){
					int temp = array[i];
					array[i] = array[j];
					array[j] = temp;
				}
				count++;
			}
		}
		System.out.println(Arrays.toString(array) + "--->ChooseSort:" + count);
	}
}

插入排序

其核心思想是把待排序区中的第一个元素拿出来,把位置给空出来。然后用该元素,跟有序区中的元素进行比较。假设是从小到大排序,则比该元素大的,往后移动一次。依次进行即可。把该元素插入到不能移动的元素后边的空间中。该排序算法是稳定的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eccwpCWP-1591368532701)(http://orxmumro7.bkt.clouddn.com/18-4-24/63642868.jpg)]

package datastructure.part.sort;

import java.util.Arrays;

/**
 * @description
 * @author Denghs
 * @version 1.0,2018年2月27日 上午9:57:20
 * @remark 插入排序:1、元素拿出来。2、符合条件的元素后移
 */
public class InsertSort {

	public static void main(String[] args) {
		// 统计运行次数
		int count = 0;
		int[] array = { 5, 4, 9, 87, 1, 2, 14, 26 };
		insertSort(array, count);
	}
	
	/**
	 * 插入排序
	 * @param array
	 * @param count
	 */
	public static void insertSort(int[] array, int count) {
		int pos = 0;
		for (int i = 2; i < array.length; i++) {
			// 待插入的位置
			pos = i;
			// 元素拿出来
			int temp = array[i];
			for (int j = i - 1; j >= 0 && array[j] > temp; j--) {
				// 符合条件的元素后移
				array[j + 1] = array[j];
				// 需要插入的位置
				pos = j;
				count++;
			}
			array[pos] = temp;
		}
		System.out.println(Arrays.toString(array) + "--->InsertSort:" + count);
	}
}

冒泡排序

其基本思想是通过相邻元素之间的比较和交换,来完成排序。有向上冒泡和向下下沉。该排序算法是稳定的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MxoJfk0q-1591368532703)(http://orxmumro7.bkt.clouddn.com/18-4-24/62153665.jpg)]

package datastructure.part.sort;

import java.util.Arrays;

/**
 * @description
 * @author Denghs
 * @version 1.0,2018年2月27日 上午10:41:21
 * @remark 冒泡排序:相邻元素之间的比较交换。一种是向上冒泡,一种是向下下沉
 */
public class BubbleSort {

	public static void main(String[] args) {
		// 统计运行次数
		int count = 0;
		int[] array1 = { 5, 4, 9, 87, 1, 2, 14, 26 };
		int[] array2 = { 5, 4, 9, 87, 1, 2, 14, 26 };
		int[] array3 = { 5, 4, 9, 87, 1, 2, 14, 26 };
		int[] array4 = { 5, 4, 9, 87, 1, 2, 14, 26 };
		
		count = bubbleSort1(array1, 0);
		System.out.println(Arrays.toString(array1) + "--->bubbleSort1:" + count);
		
		count = bubbleSort2(array2, 0);
		System.out.println(Arrays.toString(array2) + "--->bubbleSort2:" + count);
		
		count = bubbleSort3(array3, 0);
		System.out.println(Arrays.toString(array3) + "--->bubbleSort3:" + count);
		
		count = bubbleSort4(array4, 0);
		System.out.println(Arrays.toString(array4) + "--->bubbleSort4:" + count);

		int[] array5 = { 1, 2, 4, 3, 5, 6, 7, 8 };
		count = bubbleSort4(array5, 0);
		System.out
				.println(Arrays.toString(array5) + "--->bubbleSort4:" + count);
	}

	/**
	 * 向上冒泡
	 * 
	 * @param array
	 * @param count
	 */
	public static int bubbleSort1(int[] array, int count) {
		for (int i = 0; i < array.length - 1; i++) {
			for (int j = 1; j < array.length - i; j++) {
				if (array[j] < array[j - 1]) {
					int temp = array[j];
					array[j] = array[j - 1];
					array[j - 1] = temp;
				}
				count++;
			}
		}
		return count;
	}

	/**
	 * 向下下沉
	 * 
	 * @param array
	 * @param count
	 */
	public static int bubbleSort2(int[] array, int count) {
		for (int i = 0; i < array.length - 1; i++) {
			for (int j = array.length - 1; j > i; j--) {
				if (array[j] < array[j - 1]) {
					int temp = array[j];
					array[j] = array[j - 1];
					array[j - 1] = temp;
				}
				count++;
			}
		}
		return count;
	}

	/**
	 * 向上冒泡,优化
	 * 
	 * @param array
	 * @param count
	 */
	public static int bubbleSort3(int[] array, int count) {
		// 标记,true表示:元素还没有排好序
		boolean flag = true;
		for (int i = 0; i < array.length - 1 && flag; i++) {
			// 认为已经排好序
			flag = false;
			for (int j = 1; j < array.length - i; j++) {
				if (array[j] < array[j - 1]) {
					int temp = array[j];
					array[j] = array[j - 1];
					array[j - 1] = temp;
					// 元素执行了交换,则说明数据还没有排好序
					flag = true;
				}
				count++;
			}
		}
		return count;
	}

	/**
	 * 向下下沉:优化
	 * 
	 * @param array
	 * @param count
	 */
	public static int bubbleSort4(int[] array, int count) {
		// 标记,true表示:元素还没有排好序
		boolean flag = true;
		for (int i = 0; i < array.length - 1 && flag; i++) {
			// 认为已经排好序
			flag = false;
			for (int j = array.length - 1; j > i; j--) {
				if (array[j] < array[j - 1]) {
					int temp = array[j];
					array[j] = array[j - 1];
					array[j - 1] = temp;
					// 元素执行了交换,则说明数据还没有排好序
					flag = true;
				}
				count++;
			}
		}
		return count;
	}
}

希尔排序

其核心思想是对数据进行分组,然后再对分组后的数据进行插入排序算法。该排序算法是不稳定的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k4cjHvH5-1591368532705)(http://orxmumro7.bkt.clouddn.com/18-4-24/5676873.jpg)]

package datastructure.part.sort;

import java.util.Arrays;

/**
 * @description
 * @author Denghs
 * @version 1.0,2018年2月27日 下午3:23:48
 * @remark 希尔排序:对数据进行分组,然后再进行插入排序算法
 */
public class ShellSort {

	public static void main(String[] args) {
		// 统计运行次数
		int count = 0;
		int[] array = { 5, 4, 9, 87, 1, 2, 14, 26 };
		shellSort(array, count);
	}
	
	/**
	 * 希尔排序
	 * @param array
	 * @param count
	 */
	public static void shellSort(int[] array, int count) {
		int gap = array.length;
		int pos = 0;
		do {
			//业界统一实验 平均最好间隔情况
			gap = gap / 3 + 1;
			for (int i = gap; i < array.length; i += gap) {
				// 待插入的位置
				pos = i;
				// 元素拿出来
				int temp = array[i];
				for (int j = i - gap; j >= 0 && array[j] > temp; j -= gap) {
					// 符合条件的元素后移
					array[j + gap] = array[j];
					// 需要插入的位置
					pos = j;
					count++;
				}
				array[pos] = temp;
			}
		} while (gap > 1);
		System.out.println(Arrays.toString(array) + "--->ShellSort:" + count);
	}
}

快速排序

其基本思想是从待排序序列中找一个基准数,以基准数进行左右分区,其中一部分的所有数据都比另外一部分所以数据小,基准数排在两个分区序列中间。然后再按此方法对这两部分数据分别进行快速排序,递归进行,达到变成有序序列。该排序算法是不稳定的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2cc1xrv7-1591368532706)(http://orxmumro7.bkt.clouddn.com/18-4-25/59375099.jpg)]

package datastructure.part.sort;

import java.util.Arrays;

/**
 * @description
 * @author Denghs
 * @version 1.0,2018年2月27日 下午4:30:56
 * @remark 快速排序:用一个PV值,跟PV值进行比较来分区,小的放左边,大的放右边。对分过区的,再找PV值进行分区,直到分区只有一个元素
 */
public class QuickSort {

	public static void main(String[] args) {
		int[] array = { 5, 4, 9, 87, 1, 2, 14, 26 };
		quickSort(array);
		System.out.println(Arrays.toString(array) + "--->QuickSort");
	}
	
	/**
	 * @param array
	 */
	public static void quickSort(int[] array) {
		qSort(array, 0, array.length - 1);
	}
	
	/**
	 * 
	 * @param array
	 * @param low
	 * @param hight
	 */
	public static void qSort(int[] array, int low, int hight) {
		if (low < hight) {
			int pivot = partition(array, low, hight);
			// 对左区间序列排序
			qSort(array, low, pivot - 1);
			// 对右区间序列排序
			qSort(array, pivot + 1, hight);
		}
	}
	
	/**
	 * 分区
	 * @param array
	 * @param low
	 * @param hight
	 * @return
	 */
	public static int partition(int[] array, int low, int hight) {
		// 用分区后的第一个元素作为PV值
		int pv = array[low];
		while (low < hight) {
			while (low < hight && array[hight] >= pv) {
				// 比基准数大,本来就在右边,所以hight向前移动
				hight--;
			}
			if (low < hight) {
				array[low] = array[hight];
				low++;
			}
			while (low < hight && array[low] <= pv) {
				// 比基准数小,本来就在左边,所以low向前移动
				low++;
			}
			if (low < hight) {
				array[hight] = array[low];
				hight--;
			}
		}
		//把拿出来的PV数,放回到low的位置
		array[low] = pv;
		return low;
	}
}

归并排序

其基本思想是使用辅助空间,首先是对待排序序列进行拆分,以递归的方式,拆成只剩下一个的时候,再两两进行归并操作,按指定的条件进行排序。再执行最后一次归并时,如果最后一次比较后,某个序列中有多余的元素,会直接插入到辅助空间后面。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2n1yZfBt-1591368532707)(http://orxmumro7.bkt.clouddn.com/18-4-25/92988182.jpg)]

package datastructure.part.sort;

import java.util.Arrays;

/**
 * @description
 * @author Denghs
 * @version 1.0,2018年2月27日 下午7:24:42
 * @remark 归并排序:两两归并
 */
public class MergeSort {
	
	public static void main(String[] args) {
		int[] array = { 5, 4, 9, 87, 1, 2, 14, 26 };
		mergeSort(array);
		System.out.println(Arrays.toString(array) + "--->MergeSort");
	}
	
	/**
	 * @param array
	 */
	public static void mergeSort(int[] array) {
		mSort(array, array, 0, array.length - 1, array.length);
	}
	
	/**
	 * 归并排序
	 * @param src:源数组
	 * @param des:目标数组
	 * @param low:最低位
	 * @param hight:最高位
	 * @param max:最大值
	 */
	public static void mSort(int[] src, int[] des, int low, int hight, int max) {
		if (low == hight) {
			// 只有一个元素,不需要归并
			des[low] = src[low];
		} else {
			// 如果多个元素,进行两路划分
			int[] space = new int[max];
			int mid = (low + hight) / 2;
			mSort(src, space, low, mid, max);
			mSort(src, space, mid + 1, hight, max);
			// 当剩下一个元素时,递归划分结束。开始进行merge归并操作
			merge(space, des, low, mid, hight);
		}
	}

	/**
	 * 两两合并
	 * @param src
	 * @param des
	 * @param low
	 * @param mid
	 * @param hight
	 */
	public static void merge(int[] src, int[] des, int low, int mid, int hight) {
		int i = low;
		int j = mid + 1;
		int k = low;
		// 将小的放到目的地中
		while (i <= mid && j <= hight) {
			if (src[i] < src[j]) {
				des[k++] = src[i++];
			} else {
				des[k++] = src[j++];
			}
		}
		// 若还剩几个尾部元素
		while (i <= mid) {
			des[k++] = src[i++];
		}
		// 若还剩几个尾部元素
		while (j <= hight) {
			des[k++] = src[j++];
		}
	}
}

查找

二分查找法

二分查找又称折半查找,效率较高,但有限制条件。只能对线性表的顺序存储结构并且元素有序进行查找。可采用递归、非递归方式。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L82atSvH-1591368532709)(http://orxmumro7.bkt.clouddn.com/18-4-25/46051005.jpg)]

package datastructure.part.sort;

/**
 * @description
 * @author Denghs
 * @version 1.0,2018年2月28日 下午3:18:58
 * @remark 二分查找法
 */
public class BinarySearch {

	public static void main(String[] args) {
		int[] array = { 1, 2, 3, 4, 5, 6, 7, 8 };
		int index = binarySearch(array, 1, 0, array.length - 1);
		System.out.println("index:" + index);
		index = binarySearch(array, 1);
		System.out.println("index:" + index);
	}

	/**
	 * 非递归方式
	 * @param array
	 * @param keyword
	 * @return
	 */
	private static int binarySearch(int[] array, int keyword) {
		int low = 0;
		int hight = array.length - 1;
		int mid;
		while (low <= hight) {
			mid = (low + hight) / 2;
			if (keyword == array[mid]) {
				return mid;
			} else if (keyword < array[mid]) {
				hight = mid - 1;
			} else {
				low = mid + 1;
			}
		}
		return -1;
	}

	/**
	 * 递归方式
	 * @param array
	 * @param keyword
	 * @param low
	 * @param hight
	 * @return
	 */
	private static int binarySearch(int[] array, int keyword, int low, int hight) {
		if (low <= hight) {
			int mid = (low + hight) / 2;
			if (keyword == array[mid]) {
				return mid;
			} else if (keyword > array[mid]) {
				return binarySearch(array, keyword, mid + 1, hight);
			} else {
				return binarySearch(array, keyword, low, mid - 1);
			}
		}
		return -1;
	}
}

二叉排序树

**又称二叉查找树,其特点是如果右子树非空,右子树上所有结点的值均大于根节点的值。如果左子树非空,左子树上所有结点的值均小于根结点的值。左右子树又各是一棵二叉排序树。中序遍历即可获得一个有序序列。**Java中的TreeSet,其实就是一个二叉排序树,根据左小右大来放置元素。

其他代码实现

顺序栈

package datastructure.part.one;

/**
 * @description
 * @author Denghs
 * @version 1.0,2018年2月8日 上午9:37:53
 * @remark 数组结构的顺序栈
 */
public class Stack<T> {
	private int maxSize; // 栈空间的大小
	private T[] stackArray;// 顺序栈,采用泛型确定栈空间的存放的数据类型
	private int top; // 栈顶指针

	public Stack(int size) {
		maxSize = size;
		stackArray = (T[]) new Object[maxSize];
		top = -1;
	}
	
	/**
	 * 入栈
	 * @param element
	 */
	public void push(T element) {
		stackArray[++top] = element;
		if (top > (maxSize - 1)){
			top = maxSize - 1;
		}
	}

	public void pretendedPush() {
		++top;
		if (top > (maxSize - 1)) {
			top = maxSize - 1;
		}
	}
	
	/**
	 * 出栈
	 * @return
	 */
	public T pop() {
		if (top == -1) {
			return null;
		} else {
			return stackArray[top--];
		}
	}
	
	/**
	 * 查看栈顶元素,但是不出栈
	 * @return
	 */
	public T peek() {
		return stackArray[top];
	}
	
	/**
	 * 判断栈是否空
	 * @return
	 */
	public boolean isEmpty() {
		return top == -1;
	}
	
	/**
	 * 判断栈是否满
	 * @return
	 */
	public boolean isFull() {
		return top == maxSize - 1;
	}

}

进制转换

借助栈空间,根据基数对原数取余数,把取到余数入栈,再对原数取整,循环该过程,直到取整的数为0时停止。最后再栈内元素全部出栈。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9X1xae9K-1591368532710)(http://orxmumro7.bkt.clouddn.com/18-4-25/65164370.jpg)]

package datastructure.part.one;

/**
 * @description
 * @author Denghs
 * @version 1.0,2018年4月7日 上午9:17:33
 * @remark 进制转换
 */
public class BinaryConversion {

	public static void main(String[] args) {
		conversion(6, 2);
	}

	/**
	 * 进制转换的思想是,对一个原数不停的取余数
	 * @param number:原始数值
	 * @param decimalBinary:转换的进制,基数
	 */
	public static void conversion(int number, int decimalBinary) {
		// 初始化栈空间,栈的大小。取数值整除基数再加1
		Stack<Integer> stack = new Stack<Integer>(number / decimalBinary + 1);
		while (number != 0) {
			// 把余数放入栈中
			stack.push(number % decimalBinary);
			// 取整
			number = number / decimalBinary;
		}
		while (!stack.isEmpty()) {
			System.out.print(stack.pop());
		}
	}

}

判断回文数

回文的特点是:倒着写跟原来是一样的。代码的实现,用了三种方式。
第一种是判断非负整数是否是个回文数。采用的方式,是把原来的数值给回转过来,再跟原数值进行一次比较,相等则是回文数。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vMd6iJeJ-1591368532711)(http://orxmumro7.bkt.clouddn.com/18-4-25/58749426.jpg)]
第二种是采用栈,对数值的长度进行劈叉,把前一半的数值一次入栈。然后再进行出栈,并与后一半数值进行比较,都相等则是回文数。该方式有一个BUG,当长度是奇数时,前一半数据的长度跟后一半数据的长度并不相等,会导致12321这种类型的数据,判断出来不是回文数。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NNLIS4qW-1591368532713)(http://orxmumro7.bkt.clouddn.com/18-4-25/21151254.jpg)]
第三种是获取数据的字节数组,采用头指针跟尾指针,每循环一次,拿头指针上的数据与尾指针上的数据进行比较,相等则头指针往前挪一位,尾指针往后挪一位。直到头指针小于等与尾指针,循环结束。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EZBzmrrl-1591368532714)(http://orxmumro7.bkt.clouddn.com/18-4-25/1351937.jpg)]

package datastructure.part.one;

/**
 * @description
 * @author Denghs
 * @version 1.0,2018年3月5日 下午4:52:12
 * @remark 判断回文数
 */
public class Symmetry {

	public static void main(String[] args) {
		System.out.println(symmetry(1221));
		System.out.println(symmetry("哈哈哈哈"));
		System.out.println(symmetry("456654"));
		System.out.println(symmetryStr("45654"));
	}

	/**
	 * 判断一个数值是否是回文数。回文的特点是:倒着写跟原来是一样的。
	 * 
	 * @param number
	 */
	public static boolean symmetry(int number) {
		int i = 0;
		int sum = 0;
		int record = number;// 保存原记录数
		while (true) {
			i = number % 10;
			sum = sum * 10 + i;
			number /= 10;
			if (number == 0)
				break;
		}
		// 判断倒过来写的数,是否跟原来的数是一样的。
		if (sum == record) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断一个串是否是回文串。回文的特点是:倒着写跟原来是一样的。
	 * 使用栈的方式,进行比较。如果串的长度是一个奇数,会存在一个中间数没有对应的数进行比较。
	 * 则会返回false
	 * @param string
	 */
	public static boolean symmetry(String string) {
		// 获取串字符的长度
		char[] charArray = string.toCharArray();
		// 初始化栈
		Stack<Character> stack = new Stack<Character>(charArray.length / 2 + 1);
		for (int i = 0; i < charArray.length / 2; i++) {
			// 前一半的字符放入栈中
			stack.push(charArray[i]);
		}
		for (int j = charArray.length / 2; j < charArray.length; j++) {
			Character character = stack.pop();
			// 栈内已经没有元素了或者有字符不相同
			if (null == character || character != charArray[j]) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 判断一个串是否是回文串。回文的特点是:倒着写跟原来是一样的。
	 * @param string
	 */
	public static boolean symmetryStr(String string) {
		char[] charArray = string.toCharArray();
		int start = 0;
		int end = charArray.length - 1;
		while (start <= end) {
			if (charArray[start] != charArray[end]) {
				return false;
			}
			start++;
			end--;
		}
		return true;
	}
}

汉诺塔问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NPjrJU1L-1591368532715)(http://orxmumro7.bkt.clouddn.com/18-4-25/18613059.jpg)]

package datastructure.part.one;

import java.util.Scanner;

/**
 * @description 
 * @author Denghs
 * @version 1.0,2018年2月7日 上午9:37:53
 * @remark 汉诺塔问题
 */
public class HanNuoTa {
	
	public static void main(String[] args) {
		System.out.println("输入一个数字:");
		Scanner scanner = new Scanner(System.in);
		//操作数
		int number = scanner.nextInt();
		//三根柱子
		String poleA = "柱子A";
		String poleB = "柱子B";
		String poleC = "柱子C";
		//A柱子上的盘子,借助B柱子,移动到C柱子
		hanNuoTa(number, poleA, poleB, poleC);
		scanner.close();
	}

	/**
	 * @param number 盘子数
	 * @param poleA	盘子所在的柱子
	 * @param poleB 需要借力的柱子
	 * @param poleC	最终移动到的柱子
	 */
	private static void hanNuoTa(int number, String poleA, String poleB, String poleC) {
		/*
		如果是1个盘子
			直接将A柱子上的盘子从A移动到C
		否则
			先将A柱子上的n-1个盘子,借助C移动B
			直接将A柱子上的盘子从A移动到C
			最后将B柱子上的n-1个盘子,借助A移动C*/
		if(1 == number){
			System.out.println("将编号为-" + number + "的盘子,直接从柱子-" + poleA + "移动到柱子-" + poleC);
		}else{
			hanNuoTa(number-1, poleA, poleC, poleB);
			System.out.println("将编号为-" + number + "的盘子,直接从柱子-" + poleA + "移动到柱子-" + poleC);
			hanNuoTa(number-1, poleB, poleA, poleC);
		}
	}
	
}
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值