Java实现遍历、排序、查找算法及简要说明

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1.遍历算法(遍历二叉树6种方法)

1.1.概述

遍历算法针对二叉树而言的,主要有先序、中序、后序三种遍历顺序,三种顺序又分别有递归和常规算法,二叉树遍历的主要思想是:遍历左子树,遍历右子树,访问根节点,由这三者的遍历顺序来确定是先序、中序还是后序。下面只要求掌握递归遍历算法,常规遍历算法见附录一。

1.2.先序遍历算法

遍历顺序:访问根节点,遍历左子树,遍历右子树。代码如下:

void preOrder(BinaryTreeNode bt) {

if (bt == null)// 如果当前树为空,则终止递归

return;

System.out.print(bt.getData());// 先访问根节点

preOrder(bt.getLeftChild());// 再遍历左子树

preOrder(bt.getRightChild());// 再遍历右子树

}

1.3.中序遍历算法

遍历顺序:遍历左子树,访问根节点,遍历右子树。代码如下:

void midOrder(BinaryTreeNode bt) {

if (bt == null)// 如果当前树为空,则终止递归

return;

preOrder(bt.getLeftChild());// 先遍历左子树

System.out.print(bt.getData());// 再访问根节点

preOrder(bt.getRightChild());// 再遍历右子树

}

1.4.后序遍历算法

遍历顺序:遍历左子树,遍历右子树,访问根节点。代码如下:

void postOrder(BinaryTreeNode bt) {

if (bt == null)// 如果当前树为空,则终止递归

return;

preOrder(bt.getLeftChild());// 先遍历左子树

preOrder(bt.getRightChild());// 再遍历右子树

System.out.print(bt.getData());// 再访问根节点

}

1.5.层次遍历算法

void levelOrder(BinaryTreeNode bt) {

if (bt == null)

return;

Queue q = new ArrayQueue();

q.enqueue(bt);

while (!q.isEmpty()) {

bt = (BinaryTreeNode) q.dequeue();// 取出队首元素,访问之

System.out.println(bt.getData());

if (bt.hasLeftChild()) {

q.enqueue(bt.getLeftChild());// 如果左节点存在,放入队列中

}

if (bt.hasRightChild()) {

q.enqueue(bt.getRightChild());// 如果右节点存在,放入队列中

}

}

}

2.排序算法(9种排序算法)

2.1.概述

将一个数据元素的任意序列,重新排列成一个按关键字有序的序列。

2.2.插入类排序

基本思想是:逐个考察每个待排序元素,将每一个新元素插入到前面已经排好序的序列中适当的位置上,使得新序列仍然是一个有序序列。主要介绍三种:直接插入排序、折半插入排序和希尔排序。

2.2.1.直接插入排序

思路:仅有一个元素的序列总是有序的,因此,对n 个记录的序列,可从第二个元素开始直到第n 个元素,逐个向有序序列中执行插入操作,从而得到n 个元素按关键字有序的序列。代码如下:void insert(int[] a) {

for (int i = 1; i < a.length; i++) {// 从第二个开始比较插入

// 待插入的元素比之前排好序的元素最大值小才需要插入

if (a[i] < a[i - 1]) {

int tmp = a[i];// 把当前位置腾出来

a[i] = a[i - 1];// 和已排好序的最大值交换顺序

int j = i - 2;// 遍历之前i-2个元素找出要插入的位置

// 如果待插入元素小于已排好序中的第j位并j不小于0则继续遍历

for (; j >= 0 && tmp < a[j]; j--)

a[j + 1] = a[j];

a[j + 1] = tmp;// j + 1即为待插入位置

}

2.2.2.折半插入排序

思路:可以不断二分有序序列来确定插入位置,即搜索插入位置的方法可以使用折半查找实现。代码如下:void binaryInsert(int[] a) {

for (int i = 1; i < a.length; i++) {// 从第二个开始比较插入

// 待插入的元素比之前排好序的元素最大值小才需要插入

if (a[i] < a[i - 1]) {

int tmp = a[i];// 把当前位置腾出来

a[i] = a[i - 1];// 和已排好序的最大值交换顺序

int low = 0, high = i - 1, mid;//high=已排好序列的长度

while (low < high) {

mid = (low + high) / 2;

if (tmp < a[mid])

high = mid - 1;

else

low = mid + 1;

}

int j = i - 2;// 遍历之前i-2个元素找出要插入的位置

// 取high是因为经过while循环后high一定是不大于low的

for (; j > high; j--)

a[j + 1] = a[j];

a[high + 1] = tmp;// high + 1即为待插入位置

}

}

}

2.2.

3.希尔排序

思路:首先将待排序的元素分为多个子序列,使得每个子序列的元素个数相对较少,对各个子序列分别进行直接插入排序,待整个待排序序列“基本有序”后,再对所有元素进行一次直接插入排序。

static void shell(int[] a) {

int d = 1;// 定义步长值

while (d <= a.length / 3)

d = d * 3 + 1;// 根据数组长度生成步长终值

for (; d > 0; d = (d - 1) / 3) {// 还原步长值

for (int i = d; i < a.length; i++) {// 从第1个步长开始比较插入

// 待插入的元素比之前排好序的元素最大值小才需要插入

if (a[i] < a[i - d]) {

int tmp = a[i];// 把当前位置腾出来

a[i] = a[i - d];// 和已排好序的最大值交换顺序

int j = i - d - 1;// 遍历之前i-d-1个元素找出要插入的位置

// 如果待插入元素小于已排好序中的第j位并j不小于0则继续遍历

for (; j >= 0 && tmp < a[j]; j -= d)

a[j + d] = a[j];

a[j + d] = tmp;// j + d即为待插入位置

}

相关文档
最新文档