目录
试题1:快速排序
试题2:希尔排序
试题3:折半查找
试题4:堆排序
试题5:哈夫曼树的实现
试题6:二叉树的遍历
试题7:图两点最短距离
试题8:图的存储实现
试题9:二叉排序树的查找
试题10:括号匹配问题
试题11:二叉树的中序遍历
试题12:二叉树的先序遍历
试题13:二叉树的分层遍历
试题14:二叉树的后序遍历
试题1:快速排序
快速排序的核心操作是划分,通过某个数据将原来排序表分成两部分,前面部分比该数小,后面数据比该数据大或相等,该位置就为某数据排序后的位置,即该数据完成排序。如果定义一个排序表的划分方法为:
int partition(int[] R,int low,int high); 其中,low,high表示将数据R的第low个数据到high个数据进行划分,返回到整数为划分后到支点存储的位置;快速排序在查找分支点位置的方法有多种,本题目的排序过程中,首先从右向左移动,搜索小于分支记录的第一个元素,再从左向右移动,搜索大于分支记录的第一个元素,交互该两个记录值,继续搜索,直到两个搜索点交汇,如果交汇点记录与分支记录相等,分支记录与交汇点数据不交换,分支位置为交汇位置; 完成划分方法后,通过递归调用完成快速排序:
void QuickSort(int[] R,int s,int t){
if(s<t){
int i=partition(R,s,t);
QuickSort(R,s,i-1);
QuickSort(R,i+1,t);
}
}
建议每次划分选择第一个元素为支点记录进行编程。给你到问题是,将标准输入的n个整数采用快速排序,并需要显示出每次划分分支点存储的位置,第一个数为0,分支点的输出顺序按照程序递归产生的分支点的先后进行输出,并完成该数据的排序。
输入:标准输入,输入的第一行为整数的个数n值,第二行为n个整数,每个整数之间为一个空格。
输出:标准输出,输出的第一行依次输出排序过程中使用的支点位置,每个输出数据之间使用一个空格隔开,第二行输出排序后的序列,每个输出数据之间使用一个空格隔开。
输入样例:
14
39 80 76 41 13 29 50 78 30 11 100 7 41 86
输出样例:
5 3 2 1 8 6 9 13 12 10
7 11 13 29 30 39 41 41 50 76 78 80 86 100
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2016-6-6 [ 在线测试 ]
import java.util.Scanner;
//????????
public class TestQuickSort {
public static void main(String[] args) {
//????????
int n;int[] data;
Scanner in=new Scanner(System.in);
n=in.nextInt();
data=new int[n];
for(int i=0;i<n;i++)
data[i]=in.nextInt();
//????????
quicksort(data,0,data.length-1);
//???????????
System.out.println();
for(int i=0;i<n;i++)
System.out.print(data[i]+" ");
}
public static void quicksort(int[] data, int low, int high) {
if(low<high)
{
//????????
int i=partition(data,low,high);
System.out.print(i+" ");
//???????????????
quicksort(data,low, i-1);
//???????????????
quicksort(data,i+1, high);
}
}
private static int partition(int[] data, int low, int high) {
//??????????????
int i=low;
int j=high;
int temp;
//????????????????
int base=data[low];
//????????????????
while(i<j){
//1.???????????j,????????С?????????
while(i<j&&data[j]>=base)
j--;
//2.???????????i,??????????????????????data[i]
while(i<j&&data[i]<=base)
i++;
//3.???????????????
if(i<j)
{temp=data[i];
data[i]=data[j];
data[j]=temp;
}
}
//4.????????????λ??
if(data[j]<data[low])
{temp=data[low];
data[low]=data[j];
data[j]=temp;
}
return i;
}
}
试题2:希尔排序
希尔排序的思想是:先选择一个小于排序数据个数n的整数di(称为步长,一般为小于n的质数),将间隔di的数为一组,对每组的元素进行直接插入排序,即将需要排序的数据插入到已经排序好的序列中。当步长为1时,完成整个数据的排序。排序的流程为:
1、根据步长的个数,对于每个步长进行分组;
2、对每组进行插入排序,主要操作如下:
1)如果待插入数据比前一个数据小,将该数据存储到临时遍历temp中;
2)将前面比他大的数据全部向后移动一位;
3)再将temp的数据插入到最后移动的数据位置;
给你到问题是,将标准输入的n个整数采用希尔排序,步长取5,3,1,并需要显示出每次需要插入的数,并完成该数据的排序。
输入:标准输入,输入的第一行为整数的个数n值,第二行为n个整数,每个整数之 间为一个空格。
输出:标准输出,输出第一行依次输出排序过程中需要插入的数,每个输出数据之间使用一个空格隔开,第二行输出排序后的序列,每个输出数据之间使用一个空格隔开。
输入样例:
14
39 80 76 41 13 29 50 78 30 11 100 7 41 86
输出样例:
29 50 30 11 7 41 39 13 86 7 29 11 30 41 50 80 78
7 11 13 29 30 39 41 41 50 76 78 80 86 100
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2016-6-6 [ 在线测试 ]
import java.util.Scanner;
//???????
public class Shellsort {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] a = new int[n];
for(int i = 0; i < n; i++){
a[i] = in.nextInt();
}
shellsort(a);
System.out.println();
print(a);
in.close();
}
public static void shellsort(int[] data) {
int j = 0;
int temp = 0;
for (int d = 5; d > 0; d -= 2) {
for (int i = d; i < data.length; i++) {
temp = data[i];
boolean flag = true;
for (j = i; j >= d; j -= d) {
if(temp < data[j - d]){
data[j] = data[j - d];
if(flag) {
System.out.print(temp+" ");
flag = false;
}
}else break;
}
data[j] = temp;
}
}
}
public static void print(int[] R){
System.out.print(R[0]);
for(int i = 1; i < R.length; i++){
System.out.print(" " + R[i]);
}
System.out.println();
}
}
试题3:折半查找
折半查找是在有序表中,把待查找数据值与查找范围的中间元素值进行比较,会有三种情况出现:
1)待查找数据值与中间元素值正好相等,则放回中间元素值的索引。
2)待查找数据值比中间元素值小,则以整个查找范围的前半部分作为新的查找范围,执行1),直到找到相等的值。
3)待查找数据值比中间元素值大,则以整个查找范围的后半部分作为新的查找范围,执行1),直到找到相等的值
4)如果最后找不到相等的值,则返回不存储数据的备用单位0。
给你的问题是,标准输入一升序排列有序整数表,使用折半查找方法查找一个给定的整数值,查找中是通过使用表中的元素与给定的元素值进行比较完成查找,需要你依次输出在折半查找过程中使用过比较的元素值。
输入:标准输入,输入的第一行为一个正整数n,表示需要查找表的元素个数;第二行为具有升序序列的n个整数,两数之间为一个空格隔开;第三行为需要你查找的整数。
输出:标准输出,第一行依次输出在查找过程中进行比较的元素值,两数之间使用一个空格隔开。输出的第二行输出查找结果,如果查找元素在表中,输出该元素的序号(从1开始编号),如果查找元素不在表中,输出“NO"。
输入样例:
13
7 14 18 21 23 29 31 35 38 42 46 49 52
21
输出样例:
31 18 23 21
4
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2016-6-6 [ 在线测试 ]
import java.util.ArrayList;
import java.util.Scanner;
class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] a = new int[n + 1];
for (int i = 1; i <= n; i++) {
a[i] = sc.nextInt();
}
ArrayList arr = new ArrayList<>();
int x = sc.nextInt();
// 二分查找
int l = 1, r = n;
while (l <= r) {
int mid = (l + r) >> 1;
arr.add(a[mid]);
if (x > a[mid]) {
l = mid + 1;
} else if (x < a[mid]) {
r = mid - 1;
} else {
break;
}
}
for (int i = 0; i < arr.size(); i++) {
if (i > 0) System.out.print(" ");
System.out.print(arr.get(i));
}
System.out.println();
if (l <= r) {
System.out.println((l + r) >> 1);
} else {
System.out.println("NO");
}
}
}
试题4:堆排序
堆排序的思想实际上利用完全二叉树存储在数组中,通过调整完全二叉树成为大顶堆获得一个排序表的最大值进行排序的方法,大顶堆满足根节点比子树旳节点大。堆排序主要是通过大顶堆旳根元素与未完成排序旳最后一个元素进行交换,将交换后旳完全二叉树不满足大顶堆要求调整到满足满足要求,调整通过如下方法完成:
void heapAdjust(int[] R,int s,int t);其中,数组R中存储旳二叉树,只有以R[s]为根子树,其左右子树之间可能不满足大顶堆特征。
调整堆旳操作难点为根子树节点编号为i,则左子树节点编号为2*i,右子树节点编号为2*i+1;通过比较子树旳大小选择大旳子树进行调整,一直调整到根节点比子节点大,再将根节点旳值插入到最后调整旳节点。要完成堆排序,在调整旳基础上可以通过从堆底往堆顶进行调整获得初始堆,然后通过N-1次调整完成排序,控制流程为:
void heapSort(int[] R){
int i;
int N=R.length-1;
for(i=N/2;i>0;i--){
heapAdjust(R,i,N);
}
for(i=N;i>1;i--){
R[0]=R[1];R[1]=R[i];R[i]=R[0];
heapAdjust(R,1,i-1);
}
}
给你旳问题是,将标准输入的n个整数采用堆排序,并需要显示建成旳初始堆,并完成该数据的排序。
输入:标准输入,输入的第一行为整数的个数n值,第二行为n个整数,每个整数之间为一个空格。
输出:标准输出,第一行依次输出排序过程中建成旳初始堆在数组中的存储值,每个输出数据之间使用一个空格隔开,第二行输出排序后的序列,每个输出数据之间使用一个空格隔开。
输入样例:
14
39 80 76 41 13 29 50 78 30 11 100 7 41 86
输出样例:
100 80 86 78 39 41 76 41 30 11 13 7 29 50
7 11 13 29 30 39 41 41 50 76 78 80 86 100
import java.util.Scanner;
public class Heapsort {
public static void main(String[] args) {
int n;int[] data;
Scanner in=new Scanner(System.in);
n=in.nextInt();
data=new int[n];
for(int i=0;i<n;i++)
data[i]=in.nextInt();
heapSort(data);
for(int i=0;i<n;i++)
System.out.print(data[i]+" ");
System.out.println();
}
public static void heapSort(int[] data){
int i,top;
int N=data.length-1;
for(i=N/2;i>=0;i--){//创建初始堆
heapAdjust(data,i,N);
}
for(i=0;i<=N;i++)
System.out.print(data[i]+" ");
System.out.println();
for(i=N;i>0;i--){
//取出堆顶元素放在数组的最后面,数组最后的数放在堆顶再向下调整,数组的0位置不用来存储堆数据,用来交换数据的时候暂存数据
top=data[0];
data[0]=data[i];
data[i]=top;
heapAdjust(data,0,i-1);
}
}
public static void heapAdjust(int[] data,int low,int high){
int k=low;
int j=2*k+1;
int temp=data[k];
while(j<=high){
//判断右子节点是否存在,并比较左右节点的大小,和最大的交换
if((j<high)&&(j+1<=high)&&(data[j]<data[j+1]))
++j;
if(temp<data[j]){//调整完之后继续向下调整
data[k]=data[j];
k=j;
j=2*k+1;
}else{
break;
}
}
data[k]=temp;//找到该点的合适位置
}
}
试题5:哈夫曼树的实现
哈夫曼树也称为最优二叉树,是指对于一组有确定权值的叶结点、构造的具有最小带权路径长度的二叉树。给你的问题是,提供一组n个整数权值,请你完成构建该组权值的哈夫曼树。
输入:标准输入,输入的第一行为一个正整数,其值代表需要构建二叉树的叶结点的个数n;输入的第二行为n个由一个空格隔开的正整数,表示叶结点的权值;输入的第三行为n个字符,对应第二行的权值的叶结点的名称;
输出:标准输出,输出构建的哈夫曼树的每个叶结点的访问路径,即从根到叶结点的路径,如果是走左输出l,如果走右输出r。每行输出一个叶结点信息,输出格式为:先输出该结点的名称,再输出冒号,接下来,输出路径,中间仅一个空格隔开。按照输入叶结点的名称次序分别使用n行输出。
测试样例:
输入:
4
7 5 3 1
abcd
输出:
a:l
b:r r
c:r l r
d:r l l
说明,为了进行系统判断,在构建哈夫曼树时,要求:
(1)选择两个权值小的结点在构建子树时,小的结点为左子树,较大的为右子树;
(2)如果存在两个权值相同,以出现的顺序依次为左右子树;
提示:
在构建哈夫曼树时,提供设计的结点对象参考如下:
public class HFMTreeNode {
int weight,parent,lchild,rchild;
HFMTreeNode(){
weight=0;
parent=lchild=rchild=-1;
}
}
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
HFMTree ht = new HFMTree();
ht.create();
ht.print();
}
}
class HFMTreeNode {
int weight,parent,lchild,rchild;
HFMTreeNode(){
weight=0;
parent=lchild=rchild=-1;
}
}
class HFMTree{
private HFMTreeNode[] data;
private int leafNum;
private String str;
public void create() {
Scanner sc = new Scanner(System.in);
leafNum = sc.nextInt();
data = new HFMTreeNode[2 * leafNum - 1];
for (int i = 0; i < 2 * leafNum - 1; ++i) {
data[i] = new HFMTreeNode();
}
for (int i = 0; i < leafNum; ++i) {
data[i].weight = sc.nextInt();
}
str = sc.next();
sc.close();
int data1, data2, index1, index2;
for (int i = 0; i < leafNum - 1; ++i) {
data1 = data2 = Integer.MAX_VALUE;
index1 = index2 = 0;
for (int j = 0; j < leafNum + i; ++j) {
if (data[j].weight < data1 && data[j].parent == -1) {
index2 = index1;
data2 = data1;
index1 = j;
data1 = data[j].weight;
} else if (data[j].weight < data2 && data[j].parent == -1) {
index2 = j;
data2 = data[j].weight;
}
}
data[index1].parent = leafNum + i;
data[index2].parent = leafNum + i;
data[leafNum + i].weight = data[index1].weight + data[index2].weight;
data[leafNum + i].lchild = index1;
data[leafNum + i].rchild = index2;
}
}
public void print() {
int[] id = new int[leafNum];
char[][] mp = new char[leafNum][leafNum];
for (int i = 0; i < leafNum; ++i) {
int tmp = i;
while (data[tmp].parent != -1) {
int last = tmp;
tmp = data[tmp].parent;
if (data[tmp].lchild == last) {
mp[i][id[i] ++] = 'l';
} else {
mp[i][id[i] ++] = 'r';
}
}
}
for (int i = 0; i < leafNum; ++i) {
System.out.print(str.charAt(i) + ":");
for (int j = id[i] - 1; j >= 0; --j) {
System.out.print(mp[i][j] + " ");
}
System.out.println();
}
}
}
类别:[ 程序类 ] 难度:[ 较难 ] 入库时间:2017-12-25 [ 在线测试 ]
试题6:二叉树的遍历
给你一颗已经创建完成的二叉树,请你根据要求完成该树的遍历实现。提供给你的使用归档文件DSjar.jar,该文件包含了二叉树需要使用的类型和栈队列等相关类型,并提供了一个创建树的静态方法, 你可以使用该类库来创建树并完成树的遍历,遍历代码需要你自己设计完成,能提供你的仅为一个创建好的二叉树,二叉树的节点数据类型为Character,该树的创建代码如下:
LinkBiTree<Character> tree =new LinkBiTree<Character>();
LinkBiTree.create(tree);
你通过提供的引用tree完成该树的遍历,遍历可以使用递归和非递归实现。建议你在创建的对象文件中定义如下4种遍历的静态方法,然后根据需要进行调用:
static void PreOrder(LinkBiTree<Character> tree){ //先序遍历
}
static void InOrder(LinkBiTree<Character> tree){ //中序遍历
}
static void PostOrder(LinkBiTree<Character> tree){ //后序遍历
}
static void levelOrder(LinkBiTree<Character> tree){//层次遍历
}
输入:标准输入,输入为由一个空格分隔开的4个整数,其中1表示先序遍历,2表示中序遍历,
3表示后序遍历,4表示分层遍历。
输出:标准输出,根据输入的要求,各种遍历使用一行输出,每个顶点的数据为字符,字符之间使用
一个空格分开。
测试用例:
输入:
1 2 3 4
输出(非正确输出,仅参考格式):
A B C
B A C
B C A
A B C
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2017-12-22 [ 在线测试 ]
static void PreOrder(LinkBiTree<Character> tree){ //先序遍历
if (isEmpty()) {
System.out.println("Tree is empty");
return;
}
if (tree != null) {
System.out.print(tree.getData() + " ");
PostOrder(tree.getLchild());
PostOrder(tree.getRchild());
}
}
static void InOrder(LinkBiTree<Character> tree){ //中序遍历
if (isEmpty()) {
System.out.println("Tree is empty");
return;
}
if (tree != null) {
PostOrder(tree.getLchild());
System.out.print(tree.getData() + " ");
PostOrder(tree.getRchild());
}
}
static void PostOrder(LinkBiTree<Character> tree){ //后序遍历
if (isEmpty()) {
System.out.println("Tree is empty");
return;
}
if (tree != null) {
PostOrder(tree.getLchild());
PostOrder(tree.getRchild());
System.out.print(tree.getData() + " ");
}
}
static void levelOrder(LinkBiTree<Character> tree){//层次遍历
// 根结点为空
Queue<LinkBiTree<Character>> q = new LinkedList<LinkBiTree<Character>>();
// 根节点入队
q.add(tree);
// 队列非空,结点没有处理完
while (!q.isEmpty()) {
// 结点出队
LinkBiTree<Character> tmp = q.poll();
// 处理当前节点
System.out.print(tmp.getData() + " ");
if (tmp.getLchild() != null) {
q.add(temp.getLchild());
}
if (tmp.getRchild() != null) {
// 将当前结点的右孩子结点入队
q.add(tmp.getRchild());
}
}
}
试题7:图两点最短距离
网图中两点之间的最短距离可以通过Dijkstra算法进行计算,通过该算法能够计算出从源点到该图所有顶点的最短距离,给你的问题是: 通过DSjar.jar归档文件提供的使用邻接矩阵存储的图对象,计算图中任意两顶点之间的最短距离和路径。 利用类库中的MGraph的参考代码如下:
MGraph mg=new MGraph();//创建的图已经实例化了该图的邻接矩阵,你可以通过输出该矩阵进行查看
输入:标准输入,输入一行有两个正整数,分别表示起点和终点的两个顶点的序号,如果网图有5个顶点,序号从0到4。
输出:标准输出,输出格式为"A-->E distance 90 path:A-->B-->E",其中,A为源点顶点名,E为终点顶点名,90为A到E的最短距离,A-->B-->E为路径。
测试用例输入:
0 4
测试用例输出:
A-->E distance 90 path:A-->B-->E
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2017-12-26 [ 在线测试 ]
import ds.graphic.MGraph;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Stack;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 创建图
MGraph mg=new MGraph();
// 输入起点
int st = sc.nextInt();
// 输入终点
int ed = sc.nextInt();
// Dijkstra 算法求最短距离和路径
// vi 判断该顶点是否访问
boolean[] vi= new boolean[mg.vexnum];
// d 记录起点到该该点的距离
int[] d = new int[mg.vexnum];
// 初始化 距离数组d 为最大值
Arrays.fill(d, Integer.MAX_VALUE);
// path 记录该顶点的前缀顶点
int[] path = new int[mg.vexnum];
// 初始化 前缀顶点数组path 为 -1
Arrays.fill(path, -1);
// 将起点的距离改为零
d[st] = 0;
for (int i = 0; i < mg.vexnum; i++) {
// 找到距离起点最近且未访问的点
int u = -1, mx = Integer.MAX_VALUE;
for (int j = 0; j < mg.vexnum; j++) {
if (d[j] < mx && vi[j] == false) {
u = j;
}
}
// 如果发现每个顶点都已经被访问了,就退出循环
if (u == -1) break;
// 该顶点 u 被访问,则标记
vi[u] = true;
// 遍历该顶点 u 可以到达的顶点 v,并更新距离、记录其前缀顶点
for (int v = 0; v < mg.vexnum; v++) {
// 只有当从u 到 v 的距离能使得从起点到 v 点距离变短时 才更新距离
if (mg.edges[u][v] != 0 && d[u] + mg.edges[u][v] < d[v]) {
d[v] = d[u] + mg.edges[u][v];
path[v] = u;
}
}
}
// 格式化输出
System.out.print(mg.vexs[st].vname + "-->" + mg.vexs[ed].vname + " distance " + d[ed] + " path:");
// 利用栈通过前缀数组的记录找 起点st 到 终点ed 的路径
Stack<Integer> stack = new Stack<>();
stack.push(ed);
while (path[stack.peek()] != -1) {
stack.push(path[stack.peek()]);
}
System.out.print(mg.vexs[stack.pop()].vname);
while (!stack.empty()) {
System.out.print("-->" + mg.vexs[stack.pop()].vname);
}
System.out.println();
}
}
试题8:图的存储实现
图的存储方式有邻接矩阵和邻接表两种基本存储方式,通过给你提供一个图的邻接矩阵存储对象,该对象的邻接矩阵已经赋值; 请你将该图的邻接矩阵转换为邻接表存储的图对象,图的对象类型在提供给你的DSjar.jar归档文件中;你可以利用提供的库对象完成本题目的操作,在创建邻接表时,要求从编号小到大的顶点的边进行后插入,如果是无向图,也同样从编号小的顶点到编号大的顶点连接的边进行尾部插入。在MGraph对象中,已经存储了图的相关信息,创建该对象的方法如下:
MGraph mg=new MGraph();
通过该对象可以获得图的顶点、边等信息,然后利用获得的信息新建一个邻接表图对象。调用图对象的打印方法(pntALGraph())实现图的存储信息的输出。
流程控制如下:
MGraph mg=new MGraph();//创建邻接矩阵对象
int vexnum=mg.vexnum;//获得顶点数目
int edgenum=mg.edgenum;//获得边数目
boolean isdirection =mg.isdirection;//是否为有向图
ALGraph alg=new ALGraph(vexnum,edgenum,isdirection);//创建邻接表图对象
//给顶点结点数组赋值
for(int i=0;i<vexnum;i++){
alg.vextex[i]=new VexNode(mg.vexs[i]);
}
EdgeNode p=null;
//建立邻接表边链表
for(int i=0;i<vexnum;i++){
for(int j=0;j<vexnum;j++){
int w=mg.edges[i][j];
if(w>0&&w<1000){
//使用尾插入建立单链表代码
}
}
}
//输出邻接表图存储示例图
alg.pntALGraph();
输入:没有输入。
输出:输出图的邻接表,依据顶点的次序每行输出一个顶点的邻接表信息。
测试用例:
输入:无
输出(仅参考,非正确结果):
1-->[1,20,^]
2-->[2,45,-]-> [0,23,^]
3 ^
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2017-12-25 [ 在线测试 ]
import ds.graphic.ALGraph;
import ds.graphic.EdgeNode;
import ds.graphic.MGraph;
import ds.graphic.VexNode;
public class Main {
public static void main(String[] args) {
MGraph mg=new MGraph();//创建邻接矩阵对象
int vexnum=mg.vexnum;//获得顶点数目
int edgenum=mg.edgenum;//获得边数目
boolean isdirection =mg.isdirection;//是否为有向图
ALGraph alg=new ALGraph(vexnum,edgenum,isdirection);//创建邻接表图对象
//给顶点结点数组赋值
for(int i=0;i<vexnum;i++){
alg.vextex[i]=new VexNode(mg.vexs[i]);
}
EdgeNode p=null;
//建立邻接表边链表
for(int i=0;i<vexnum;i++){
for(int j=0;j<vexnum;j++){
int w=mg.edges[i][j];
if(w>0&&w<1000){
//使用尾插入建立单链表代码
p = new EdgeNode(j, w);
if (alg.vextex[i].firstedge == null) {
alg.vextex[i].firstedge = p;
} else {
EdgeNode e = alg.vextex[i].firstedge;
while (e.next != null) {
e = e.next;
}
e.next = p;
}
}
}
}
//输出邻接表图存储示例图
alg.pntALGraph();
}
import java.util.Scanner;
import java.util.Stack;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 输入顶点个数
int vexnum = sc.nextInt();
// 输入顶点
String s = sc.next();
// 输入图
int[][] ver = new int[vexnum][vexnum];
for (int i = 0; i < vexnum; i++) {
for (int j = 0; j < vexnum; j++) {
ver[i][j] = sc.nextInt();
}
}
// 输入起点
char first = sc.next().charAt(0);
String dfs = "";
// 找到起点
int root = 0;
for (int i = 0; i < vexnum; i++) {
if (s.charAt(i) == first) {
root = i;
break;
}
}
// 利用栈遍历图
Stack<Integer> st = new Stack<>();
st.add(root);
boolean[] vi = new boolean[vexnum];
vi[root] = true;
while (!st.isEmpty()) {
int top = st.pop();
dfs += s.charAt(top);
for (int i = 0; i < vexnum; i++) {
if (ver[top][i] != 0 && vi[i] == false) {
vi[i] = true;
st.add(i);
}
}
}
// 输出图的深度优先搜索
for (int i = 0; i < dfs.length(); i++) {
if (i > 0) System.out.print(" ");
System.out.print(dfs.charAt(i));
}
System.out.println();
}
}
// 图的广度优先搜索
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 输入顶点个数
int vexnum = sc.nextInt();
// 输入顶点
String s = sc.next();
// 输入图
int[][] ver = new int[vexnum][vexnum];
for (int i = 0; i < vexnum; i++) {
for (int j = 0; j < vexnum; j++) {
ver[i][j] = sc.nextInt();
}
}
// 输入起点
char first = sc.next().charAt(0);
String bfs = "";
// 找到起点
int root = 0;
for (int i = 0; i < vexnum; i++) {
if (s.charAt(i) == first) {
root = i;
break;
}
}
// 利用队列遍历图
Queue<Integer> q = new LinkedList<>();
q.add(root);
boolean[] vi = new boolean[vexnum];
vi[root] = true;
while (!q.isEmpty()) {
int top = q.poll();
bfs += s.charAt(top);
for (int i = vexnum - 1; i >= 0; i--) {
if (ver[top][i] != 0 && vi[i] == false) {
vi[i] = true;
q.add(i);
}
}
}
// 输出图的广度优先搜索
for (int i = 0; i < bfs.length(); i++) {
if (i > 0) System.out.print(" ");
System.out.print(bfs.charAt(i));
}
System.out.println();
}
}
试题9:二叉排序树的查找
二叉排序树或是一棵空树,或者是具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它根结点的值。
(2)若右子树不空,则右子树上所有结点的值均大于或等于它根结点的值。
(3)左、右子树也分别为二叉排序树。
(4)没有键值相等的节点。
给你的问题是,标准输入一整数表,使用该方法查找一个给定的整数值,查找中是通过使用表中的元素与给定的元素值进行比较完成查找,需要你依次输出在二叉排序树查找结果和查找过程,并输出比较次数,与一个记录的比较仅算1次。
输入:标准输入,输入的第一行为两个正整数n,key,n表示需要查找表的元素个数,key表示需要完成查找的关键字;第二行为n个整数,两数之间为一个空格隔开,并没有相同的两个数。
输出:标准输出,第一行依次输出在查找过程中进行比较的元素值,两数之间使用一个空格隔开。输出的第二行输出查找结果,如果查找成功,输出“YES”,如果查找元素不在表中,输出“NO"。输出的第三行为本次查找过程中比较的总次数。
输入样例:
11 80
70 30 40 10 80 20 90 100 75 60 45
输出样例:
70 80
true
2
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2019-12-20 [ 在线测试 ]
import java.util.ArrayList;
import java.util.Scanner;
class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int key = sc.nextInt();
LinkBiTree lb = new LinkBiTree();
for (int i = 0; i < n; ++i) {
int num = sc.nextInt();
lb.insert(num);
}
boolean flag = lb.search(key);
ArrayList list = lb.getList();
for (int i = 0; i < list.size(); i++) {
if (i > 0) System.out.print(" ");
System.out.print(list.get(i));
}
System.out.println();
System.out.println(flag);
System.out.println(list.size());
}
}
class LinkBiTree{
// 定义一个结点类
private static class Node{
int data;
Node lchild;
Node rchild;
public Node(int data, Node lchild, Node rchild) {
this.data = data;
this.lchild = lchild;
this.rchild = rchild;
}
public Node(int data) {
this(data, null, null);
}
}
public LinkBiTree() {
head = null;
list = new ArrayList<>();
}
private Node head;
private ArrayList list;
ArrayList getList() {
return list;
}
// 利用递归二叉树加入结点
void insert(int data) {
head = insert(data, head);
}
private Node insert(int data, Node p) {
if (p == null) {
return new Node(data);
} else if (data > p.data) {
p.rchild = insert(data, p.rchild);
} else if (data < p.data) {
p.lchild = insert(data, p.lchild);
}
return p;
}
// 利用递归查找元素
boolean search(int data) {
return search(data, head);
}
private boolean search(int data, Node p) {
if (p == null)
return false;
list.add(p.data);
if (data < p.data) {
return search(data, p.lchild);
} else if (data > p.data) {
return search(data, p.rchild);
}
return true;
}
}
试题10:括号匹配问题
检验符号是否匹配. '['和']', '('和')'成对出现时字符串合法. 例如"[][]()", "[[([]([])()[])]]"是合法的; "([(])", "[())"是不合法的.请你利用栈来解决括号的匹配问题。提示,可以使用Java库提供的栈对象进行编程。
输入:
标准输入,输入的第一行为一个正整数,表示输入行的数目N,接下来的N行每行为由括号字符组成的字符串,每行字符串的长度不超过100。
输出:
标准输出,使用N行输出输入的每行字符串是否为合法,如果合法输出“true”,否则输出“false”。
测试样例:
输入:
2
[][]()
[[([]([])())([])[]
输出
true
false
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2019-10-11 [ 在线测试 ]
import java.util.Scanner;
import java.util.Stack;
class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
sc.nextLine();
while (n-- > 0) {
String s = sc.nextLine();
Stack<Character> q = new Stack<>();
for (int i = 0; i < s.length(); i++) {
if (!q.isEmpty() && ((s.charAt(i) == ')' && q.peek().equals('('))
|| (s.charAt(i) == ']' && q.peek().equals('[')))) {
q.pop();
} else {
q.push(s.charAt(i));
}
}
System.out.println(q.isEmpty());
}
}
}
试题11:二叉树的中序遍历
给你一颗已经创建完成的二叉树,请你根据要求完成该树的遍历实现。提供给你的使用归档文件DSjar.jar,该文件包含了二叉树需要使用的类型和栈队列等相关类型,并提供了一个创建树的静态方法, 你可以使用该类库来创建树并完成树的遍历,遍历代码需要你自己设计完成,能提供你的仅为一个创建好的二叉树,二叉树的节点数据类型为Character,该树的创建代码如下:
LinkBiTree<Character> tree =new LinkBiTree<Character>();
LinkBiTree.create(tree);
你通过提供的引用tree完成该树的中序遍历,遍历可以使用递归和非递归实现。建议你在创建的对象文件中定义如下遍历的静态方法,然后根据需要进行调用:
static void InOrder(LinkBiTree<Character> tree){ //中序遍历
}
输入:无数据输入。
输出:标准输出,使用一行输出该二叉树的中序遍历结果,每个顶点的数据为字符,字符之间使用一个空格分开。
测试用例:
输出(非正确输出,仅参考格式):
B A C
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2019-12-31 [ 在线测试 ]
static void InOrder(LinkBiTree<Character> tree){ //中序遍历
if (isEmpty()) {
System.out.println("Tree is empty");
return;
}
if (tree != null) {
PostOrder(tree.getLchild());
System.out.print(tree.getData() + " ");
PostOrder(tree.getRchild());
}
}
试题12:二叉树的先序遍历
给你一颗已经创建完成的二叉树,请你根据要求完成该树的遍历实现。提供给你的使用归档文件DSjar.jar,该文件包含了二叉树需要使用的类型和栈队列等相关类型,并提供了一个创建树的静态方法, 你可以使用该类库来创建树并完成树的遍历,遍历代码需要你自己设计完成,能提供你的仅为一个创建好的二叉树,二叉树的节点数据类型为Character,该树的创建代码如下:
LinkBiTree<Character> tree =new LinkBiTree<Character>();
LinkBiTree.create(tree);
你通过提供的引用tree完成该树的先序遍历,遍历可以使用递归和非递归实现。建议你在创建的对象文件中定义如下遍历的静态方法,然后根据需要进行调用:
static void PreOrder(LinkBiTree<Character> tree){ //先序遍历
}
输入:无数据输入。
输出:标准输出,使用一行输出该二叉树的先序遍历结果,每个顶点的数据为字符,字符之间使用一个空格分开。
测试用例:
输出(非正确输出,仅参考格式):
A B C
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2019-12-31 [ 在线测试 ]
static void PreOrder(LinkBiTree<Character> tree){ //先序遍历
if (isEmpty()) {
System.out.println("Tree is empty");
return;
}
if (tree != null) {
System.out.print(tree.getData() + " ");
PostOrder(tree.getLchild());
PostOrder(tree.getRchild());
}
}
试题13:二叉树的分层遍历
给你一颗已经创建完成的二叉树,请你根据要求完成该树的遍历实现。提供给你的使用归档文件DSjar.jar,该文件包含了二叉树需要使用的类型和栈队列等相关类型,并提供了一个创建树的静态方法, 你可以使用该类库来创建树并完成树的遍历,遍历代码需要你自己设计完成,能提供你的仅为一个创建好的二叉树,二叉树的节点数据类型为Character,该树的创建代码如下:
LinkBiTree<Character> tree =new LinkBiTree<Character>();
LinkBiTree.create(tree);
你通过提供的引用tree完成该树的分层遍历,遍历可以使用递归和非递归实现。建议你在创建的对象文件中定义如下遍历的静态方法,然后根据需要进行调用:
static void levelOrder(LinkBiTree<Character> tree){//层次遍历
}
输入:无数据输入。
输出:标准输出,使用一行输出该二叉树的分层遍历结果,每个顶点的数据为字符,字符之间使用一个空格分开。
测试用例:
输出(非正确输出,仅参考格式):
A B C
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2019-12-31 [ 在线测试 ]
static void levelOrder(LinkBiTree<Character> tree){//层次遍历
// 根结点为空
Queue<LinkBiTree<Character>> q = new LinkedList<LinkBiTree<Character>>();
// 根节点入队
q.add(tree);
// 队列非空,结点没有处理完
while (!q.isEmpty()) {
// 结点出队
LinkBiTree<Character> tmp = q.poll();
// 处理当前节点
System.out.print(tmp.getData() + " ");
if (tmp.getLchild() != null) {
q.add(temp.getLchild());
}
if (tmp.getRchild() != null) {
// 将当前结点的右孩子结点入队
q.add(tmp.getRchild());
}
}
}
试题14:二叉树的后序遍历
给你一颗已经创建完成的二叉树,请你根据要求完成该树的遍历实现。提供给你的使用归档文件DSjar.jar,该文件包含了二叉树需要使用的类型和栈队列等相关类型,并提供了一个创建树的静态方法, 你可以使用该类库来创建树并完成树的遍历,遍历代码需要你自己设计完成,能提供你的仅为一个创建好的二叉树,二叉树的节点数据类型为Character,该树的创建代码如下:
LinkBiTree<Character> tree =new LinkBiTree<Character>();
LinkBiTree.create(tree);
你通过提供的引用tree完成该树的后序遍历,遍历可以使用递归和非递归实现。建议你在创建的对象文件中定义如下遍历的静态方法,然后根据需要进行调用:
static void PostOrder(LinkBiTree<Character> tree){ //后序遍历
}
输入:无数据输入。
输出:标准输出,使用一行输出该二叉树的后序遍历结果,每个顶点的数据为字符,字符之间使用一个空格分开。
测试用例:
输出(非正确输出,仅参考格式):
B C A
类别:[ 程序类 ] 难度:[ 中等 ] 入库时间:2019-12-31 [ 在线测试 ]
static void PostOrder(LinkBiTree<Character> tree){ //后序遍历
if (isEmpty()) {
System.out.println("Tree is empty");
return;
}
if (tree != null) {
PostOrder(tree.getLchild());
PostOrder(tree.getRchild());
System.out.print(tree.getData() + " ");
}
}