java数据结构期末复习_java数据结构复习02

1.递归问题

1.1计算阶乘

packageinterview.recursion;importjava.util.Scanner;public classFact {public static voidmain(String[] args) {

System.out.println("请输入n的值:");

Scanner in= newScanner(System.in);int n =in.nextInt();int num =fact(n);

System.out.println(n+ "的阶乘为:" +num);

}public static int fact(intn) {if (n == 1) {return 1;

}return n * fact(n - 1);

}

}

5a29dbf94cac63c359853b1c77270153.png

1.2计算斐波那契数列

Fibonacci sequence:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ……

packageinterview.recursion;importjava.util.Scanner;public classFib {public static int fib(intn) {if (n == 0) {return 0;

}else if (n == 1) {return 1;

}else{return fib(n - 1) + fib(n - 2);

}

}public static voidmain(String[] args) {

System.out.println("请输入n的值:");

Scanner in= newScanner(System.in);int n =in.nextInt();int num =fib(n);

System.out.println("第" + n + "个值的fib为:" + +num);

}

}

d5a819500beeb2f52da4df4482b67c84.png

1.3计算最大公约数(辗转相除法)

c8a0a10ceea9ece895fa031f48218644.png

d2e3d4d1689dc96e4614665222ba39bd.png

1b0044639ee432a4230e74049744a1f3.png

packageinterview.recursion;importjava.util.Scanner;public classGcd {public static int gcd(int max, intmin) {if (min == 0) {returnmax;

}else{return gcd(min, max %min);

}

}public static voidmain(String[] args) {

System.out.println("请输入max的值:");

Scanner in= newScanner(System.in);int max =in.nextInt();

System.out.println("请输入min的值:");int min =in.nextInt();int num =gcd(max, min);

System.out.println(max+ "和" + min + "的最大公约数为:" +num);

}

}

f1d7b240aab5e817047b7a2743b34e43.png

1.4汉诺塔问题(递归)

问题描述

三个柱子,起初有若干个按大小关系顺序安放的盘子,需要全部移动到另外一个柱子上。移动规则:在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

移动次数: f(n)=2n -1

解法思路

使用递归算法进行处理。

汉诺塔的算法大概有3个步骤:

(1)把a上的n-1个盘通过c移动到b。

(2)把a上的最下面的盘移到c。

(3)因为n-1个盘全在b上了,所以把b当做a重复以上步骤就好了。

在网上找到一个3阶的汉诺塔递归过程示意图,参考一下。

02ee580afaaf1224ea7d1e3466de1cc0.png

packagecn.jxufe.ch06_hanoitowers;public classHanoiTowers {/*** 汉诺塔问题:所有的盘子,刚开始都在塔座A上,要求将所有的盘子从塔座A移动到塔座C,每次只能移动一个盘子,且

* 任何盘子不能放在比自己小的盘子上。

*

*@paramtopN:移动的盘子数

*@paramfrom:从哪个塔座开始

*@paraminter:中间塔座

*@paramto;目标塔座*/

public static void doTower(int topN, char from, char inter, charto) {if (topN == 1) {

System.out.println("盘子1,从" + from + "塔座到" + to + "塔座");return;

}else{

doTower(topN- 1, from, to, inter);

System.out.println("盘子" + topN + ",从" + from + "塔座到" + to + "塔座");

doTower(topN- 1, inter, from, to);

}

}

}

packagecn.jxufe.ch06_hanoitowers;public classTestHanoiTowers {public static voidmain(String[] args) {

HanoiTowers.doTower(4,'A','B','C');

}

}

491cb46eacf1737cb57990f041253afa.png

1.5瓶盖问题

packagetest;/** 描述:每 3 个可乐盖可兑换 1 瓶子可乐,求买 n 瓶可乐最终可获得的可乐瓶子数。*/

importjava.util.Scanner;public classT03 {public static int times = 1;public static voidmain(String[] args) {

Scanner input= newScanner(System.in);

System.out.print("输入购买的可乐数:");

times= 1;int j =input.nextInt();int i =func(j);

System.out.println("--------------------------");

System.out.println("总共可获得 " + i + " 瓶\n\n");

}public static int func(inti) {if (i < 3) {

System.out.println("最终剩下 " + i + " 个瓶盖,不足以兑换");returni;

}else{

System.out.println("第 " + times++ + " 次兑换," + "本次兑换总共有 " + i + " 个瓶盖,用 " + (i - i % 3) + " 个瓶盖换了 " + i / 3

+ " 瓶可乐,剩余 " + i % 3 + " 个瓶盖可用于下次兑换");return ((i - i % 3) + func(i / 3 + i % 3));

}

}

}

50152bc4e1168408511b4d7155237db3.png

1.6走楼梯

题目描述:

一个台阶总共有n级,如果一次可以跳1级,也可以跳2级。求总共有多少总跳法。

思路:当n大于2的时候,每次可以选择走2级也可以选择走1级,所有都有两种方案。即f(n-1)+f(n-2)

packageinterview.recursion;importjava.util.Scanner;public classStairs {public static int solve(intn) {if (n == 1) {return 1;

}else if (n == 2) {return 2;

}else{return solve(n - 1) + solve(n - 2);

}

}public static voidmain(String[] args) {

System.out.println("请输入n的值:");

Scanner in= newScanner(System.in);int n =in.nextInt();int num =solve(n);

System.out.println("总共有" + num + "种走法");

}

}

0447ca4bdc736498922e6c78e0312082.png

2.二叉树

2.1插入和查找

89d0408b7a96666a837986c67945be0a.png

packagecn.jxufe.ch07_tree;/*** 二叉树节点*/

public classNode {//数据项

public intdata;publicString sdata;publicNode leftChild;publicNode rightChild;public Node(intdata,String sdata) {this.data =data;this.sdata =sdata;

}

}

packagecn.jxufe.ch07_tree;/*** 二叉树*/

public classTree {//根节点

publicNode root;/*** 插入节点*/

public void insert(intvalue,String sdata) {//封装节点

Node newNode = newNode(value,sdata);//引用当前节点

Node current =root;//引用父节点

Node parent;//如果root为null,也就是第一次插入的节点

if (root == null) {

root=newNode;return;

}else{while (true) {//父节点指向当前节点

parent =current;//如果当前节点指向的数据,比插入的要大,则向左走

if (value

current=current.leftChild;if (current == null) {

parent.leftChild=newNode;return;

}

}else{

current=current.rightChild;if (current == null) {

parent.rightChild=newNode;return;

}

}

}

}

}/*** 查找节点*/

public Node find(intvalue) {//引用当前节点,从根节点开始

Node current =root;//只要查找的值,不等于当前节点的值

while (current.data !=value) {//比较查找值,与当前节点值的大小

if (current.data >value) {

current=current.leftChild;

}else{

current=current.rightChild;

}//如果查找不到

if (current == null) {return null;

}

}returncurrent;

}/*** 删除节点*/

public void delete(intvalue) {

}

}

packagecn.jxufe.ch07_tree;public classTestTree {public static voidmain(String[] args) {

Tree tree= newTree();

tree.insert(10, "zhangsan");

tree.insert(20, "lisi");

tree.insert(3, "wangwu");

tree.insert(14, "zhaoliu");

tree.insert(76, "zhouqi");

System.out.println(tree.root.data);

System.out.println(tree.root.leftChild.data);

System.out.println(tree.root.rightChild.data);

System.out.println(tree.root.rightChild.leftChild.data);

System.out.println(tree.root.rightChild.rightChild.data);

Node node= tree.find(20);

System.out.println(node.data+ "," +node.sdata);

System.out.println(node.rightChild.data+ "," +node.rightChild.sdata);

}

}

f1560568683d13145988137c015bc8a1.png

2.2遍历二叉树

6374d68c284c08690d9f1872c49ddb45.png

packagecn.jxufe.ch07_tree;/*** 二叉树节点*/

public classNode {//数据项

public intdata;publicString sdata;publicNode leftChild;publicNode rightChild;public Node(intdata,String sdata) {this.data =data;this.sdata =sdata;

}

}

packagecn.jxufe.ch07_tree;/*** 二叉树*/

public classTree {//根节点

publicNode root;/*** 插入节点*/

public void insert(intvalue, String sdata) {//封装节点

Node newNode = newNode(value, sdata);//引用当前节点

Node current =root;//引用父节点

Node parent;//如果root为null,也就是第一次插入的节点

if (root == null) {

root=newNode;return;

}else{while (true) {//父节点指向当前节点

parent =current;//如果当前节点指向的数据,比插入的要大,则向左走

if (value

current=current.leftChild;if (current == null) {

parent.leftChild=newNode;return;

}

}else{

current=current.rightChild;if (current == null) {

parent.rightChild=newNode;return;

}

}

}

}

}/*** 查找节点*/

public Node find(intvalue) {//引用当前节点,从根节点开始

Node current =root;//只要查找的值,不等于当前节点的值

while (current.data !=value) {//比较查找值,与当前节点值的大小

if (current.data >value) {

current=current.leftChild;

}else{

current=current.rightChild;

}//如果查找不到

if (current == null) {return null;

}

}returncurrent;

}/*** 删除节点*/

public void delete(intvalue) {

}/*** 前序遍历*/

public voidfrontOrder(Node localNode) {if (localNode != null) {//访问根节点

System.out.print(localNode.data + ":" + localNode.sdata + " ");//前序遍历左子树

frontOrder(localNode.leftChild);//前序遍历右子树

frontOrder(localNode.rightChild);

}

}/*** 中序遍历*/

public voidinOrder(Node localNode) {if (localNode != null) {//中序遍历左子树

inOrder(localNode.leftChild);//访问根节点

System.out.print(localNode.data + "," + localNode.sdata + " ");//中序遍历右子树

inOrder(localNode.rightChild);

}

}/*** 后序遍历*/

public voidafterOrder(Node localNode) {if (localNode != null) {//后序遍历左子树

afterOrder(localNode.leftChild);//后序遍历右子树

afterOrder(localNode.rightChild);//访问根节点

System.out.print(localNode.data + "," + localNode.sdata + " ");

}

}

}

packagecn.jxufe.ch07_tree;public classTestTree {public static voidmain(String[] args) {

Tree tree= newTree();

tree.insert(10, "zhangsan");

tree.insert(20, "lisi");

tree.insert(3, "wangwu");

tree.insert(14, "zhaoliu");

tree.insert(76, "zhouqi");

tree.insert(13, "zhuba");

System.out.println("前序遍历:");

tree.frontOrder(tree.root);

System.out.println();

System.out.println("中序遍历:");

tree.inOrder(tree.root);

System.out.println();

System.out.println("后序遍历:");

tree.afterOrder(tree.root);

}

}

eb97714454c2770b01246919094e114b.png

2.3删除二叉树节点

034bec1b1f7f23f5bd571689724ea34c.png

packageinterview;public classTree {privateNode root;public void insertNode(intdata, String sdata) {

Node newNode= newNode(data, sdata);//引用当前节点

Node current =root;

Node parent;//如果root为null,也就是第一次插入

if (root == null) {

root=newNode;

}else{while (true) {

parent=current;//如果当前节点指向的数据,比插入的节点数据要大,则向左走

if (data

current=current.leftChildNode;if (current == null) {

parent.leftChildNode=newNode;return;

}

}else{

current=current.rightChildNode;if (current == null) {

parent.rightChildNode=newNode;return;

}

}

}

}

}public Node findNode(intvalue) {

Node current=root;while (current.data !=value) {if (current.data >value) {

current=current.leftChildNode;

}else{

current=current.rightChildNode;

}if (current == null) {return null;

}

}returncurrent;

}public voidfontOrder(Node root) {if (root != null) {

System.out.println(root.data);

fontOrder(root.leftChildNode);

fontOrder(root.rightChildNode);

}

}publicNode getSuccessor(Node delNode) {

Node successor=delNode;

Node successorParent=delNode;

Node current=delNode.rightChildNode;while (current != null) {

successorParent=successor;

successor=current;

current=current.leftChildNode;

}if(successor !=delNode.rightChildNode) {

successorParent.leftChildNode=successor.rightChildNode;

successor.rightChildNode=delNode.rightChildNode;

}returnsuccessor;

}public boolean deleteNode(intvalue) {//引用当前节点为根节点

Node current =root;//引用当前节点的父节点

Node parent =root;//是否为左子树

boolean isLeftchild = true;//查找

while (current.data !=value) {

parent=current;//比较

if (current.data >value) {

current=current.leftChildNode;

isLeftchild= true;

}else{

current=current.rightChildNode;

isLeftchild= false;

}if (current == null) {return false;

}

}//删除

if (current.leftChildNode == null && current.rightChildNode == null) {//1. 删除的节点为叶子节点

if (current ==root) {

root= null;

}else if (isLeftchild) {//如果它是父节点的左子节点

parent.leftChildNode = null;

}else{

parent.rightChildNode= null;

}

}else if (current.rightChildNode == null) { //2. 该节点有一个子节点,且为左子节点

if (current ==root) {

root=current.leftChildNode;

}else if(isLeftchild) {

parent.leftChildNode=current.leftChildNode;

}else{

parent.rightChildNode=current.leftChildNode;

}

}else if (current.leftChildNode == null) { //该节点只有一个节点,且为右子节点

if (current ==root) {

root=current.rightChildNode;

}else if(isLeftchild) {

parent.leftChildNode=current.rightChildNode;

}else{

parent.rightChildNode=current.rightChildNode;

}

}else{

Node successor= getSuccessor(current);//查找中序后继节点

if(current == root) { //以下是完成替换功能

root =successor;

}else if(isLeftchild) {

parent.leftChildNode=successor;

}else{

parent.rightChildNode=successor;

}

successor.leftChildNode=current.leftChildNode;

}return true;

}public static voidmain(String[] args) {

Tree tree= newTree();

tree.insertNode(10, "zhangsan");

tree.insertNode(20, "lisi");

tree.insertNode(3, "wangwu");

tree.insertNode(14, "zhaoliu");

tree.insertNode(76, "zhouqi");

tree.insertNode(5, "niaho");//System.out.println(tree.root.data);//System.out.println(tree.root.leftChildNode.data);//System.out.println(tree.root.rightChildNode.data);//System.out.println(tree.root.rightChildNode.leftChildNode.data);//System.out.println(tree.root.rightChildNode.rightChildNode.data);//Node node = tree.findNode(20);//System.out.println(node.data + "," + node.sdata);//System.out.println(node.rightChildNode.data + "," +//node.rightChildNode.sdata);

tree.fontOrder(tree.root);

tree.deleteNode(3);

System.out.println("--------------------");

tree.fontOrder(tree.root);

tree.deleteNode(20);

System.out.println("------------------------");

tree.fontOrder(tree.root);

}

}classNode {//数据域

public intdata;publicString sdata;//指针域

publicNode leftChildNode;publicNode rightChildNode;public Node(intdata, String sdata) {//TODO Auto-generated constructor stub

this.data =data;this.sdata =sdata;

}

}

2.4根据中序和后序,求前序遍历

packageexam;importjava.util.Arrays;public classMain {public static voidmain(String[] args) {//TODO Auto-generated method stub//Scanner sc = new Scanner(System.in);//String in = sc.nextLine();

String in = "dgbaechf";char[] inArray =in.toCharArray();//String last = sc.nextLine();

String last = "gbdehfca";char[] lastArray =last.toCharArray();//System.out.println(Arrays.toString(preArray));//System.out.println(Arrays.toString(inArray));

Node node =buildTree(inArray, lastArray);

frontOrder(node);

}public static Node buildTree(char[] inorder, char[] postorder) {if (inorder == null || postorder == null || inorder.length == 0 || postorder.length == 0) {return null;

}//将后序遍历的最后一个节点取出为根

Node root = new Node(postorder[postorder.length - 1]);int i = 0;//记录中序遍历根的位置

for (; i < inorder.length; i++) {if (postorder[postorder.length - 1] ==inorder[i]) {break;

}

}//构造左子树

char[] leftIn = Arrays.copyOfRange(inorder, 0, i);char[] leftPost = Arrays.copyOfRange(postorder, 0, i);//构造右子树

char[] rightIn = Arrays.copyOfRange(inorder, i + 1, inorder.length);char[] rightPost = Arrays.copyOfRange(postorder, i, postorder.length - 1);//左子树

root.leftChild =buildTree(leftIn, leftPost);//右子树

root.rightChild =buildTree(rightIn, rightPost);returnroot;

}/*** 前序遍历*/

public static voidfrontOrder(Node localNode) {if (localNode != null) {//访问根节点

System.out.print(localNode.data + " ");//前序遍历左子树

frontOrder(localNode.leftChild);//前序遍历右子树

frontOrder(localNode.rightChild);

}

}

}/*** 二叉树节点*/

classNode {//数据项

public chardata;publicNode leftChild;publicNode rightChild;public Node(chardata) {this.data =data;

}

}

11b7f26898baed16153aee33bc9475bd.png

2.5二叉树高度

51d667d46ce5a6ae9cf26b087383efb3.png

packagedatastruct.t04tree;/*** 二叉树节点

**/

public classNode {public intdata;publicNode leftChild;publicNode rightChild;public Node(intdata) {this.data =data;

}public voidsetLeftChild(Node leftChild) {this.leftChild =leftChild;

}public voidsetRightChild(Node rightChild) {this.rightChild =rightChild;

}public static Node createNode(intdata) {

Node node= newNode(data);

node.leftChild= node.rightChild = null;returnnode;

}public static voidsetChild(Node node, Node leftChild, Node rightChild) {

node.setLeftChild(leftChild);

node.setRightChild(rightChild);

}

}

packagedatastruct.t04tree;public classBiTree {public static intgetTreeHeight(Node root) {if (root == null) {return 0;

}else{int leftHeight =getTreeHeight(root.leftChild);int rightHeight =getTreeHeight(root.rightChild);return Math.max(leftHeight, rightHeight) + 1;

}

}public static voidmain(String[] args) {//快速构建一棵二叉树

Node root = Node.createNode(1);

Node node2= Node.createNode(2);

Node node3= Node.createNode(3);

Node node4= Node.createNode(4);

Node node5= Node.createNode(5);

Node node6= Node.createNode(6);

Node node7= Node.createNode(7);

Node node8= Node.createNode(8);

Node.setChild(root, node2, node3);

Node.setChild(node2, node4, node5);

Node.setChild(node3,null, node7);

Node.setChild(node4,null, node8);

Node.setChild(node5, node6,null);//树的高度

int height =getTreeHeight(root);

System.out.print("树的高度为:");

System.out.println(height);

}

}

a616c2a3707fbadd53792472eaf8f632.png

2.6表达式树的输出与求值

表达式树的特征:叶节点是运算数,非叶节点一定是运算符

0991a455f4c22095da81965ad87cd6bd.png

输入格式:

第一行给出节点的个数N,每个节点的编号为0 ~ N-1

接下来N行每行分别给出:

该节点的编号、该节点的操作数/操作符、该节点的左孩子编号、右孩子编号(-1表示NULL)

输出格式:

第一行输出该表达式树的中缀表达式,该用括号的地方需要用括号括起来。

第二行输出该表达式树的前缀表达式。

第二行输出该表达式树的后缀表达式。

第四行输出该表达式树的计算结果,保留两位小数。

样例输入:

11

0 - 1 2

1 + 3 4

2 / 5 6

3 4 -1 -1

4 * 7 8

5 6 -1 -1

6 3 -1 -1

7 1 -1 -1

8 - 9 10

9 5 -1 -1

10 2 -1 -1

样例输出:

(4+(1*(5-2)))-(6/3)- + 4 * 1 - 5 2 / 6 3

4 1 5 2 - * + 6 3 / -

5.00

packagedatastruct.t04tree.exptree;public classNode {chardata;

Node leftChild;

Node rightChild;

}

packagedatastruct.t04tree.exptree;importjava.util.Scanner;public classExpTree {//中缀表达式

public static void inOrder(Node root, intlayer) {if (root == null)return;if (root.leftChild == null && root.rightChild == null) {//叶结点是操作数,直接输出,不加括号

System.out.print(root.data + " ");

}else{//非叶节点是操作符,需加括号(第0层根节点除外)

if (layer > 0) {

System.out.print("(");

}

inOrder(root.leftChild, layer+ 1);

System.out.print(root.data+ " ");

inOrder(root.rightChild, layer+ 1);if (layer > 0) {

System.out.print(")");

}

}

}//前缀表达式

public static voidpreOrder(Node root) {if (root == null)return;

System.out.print(root.data+ " ");

preOrder(root.leftChild);

preOrder(root.rightChild);

}//后缀表达式

public static voidpostOrder(Node root) {if (root == null)return;

postOrder(root.leftChild);

postOrder(root.rightChild);

System.out.print(root.data+ " ");

}public static doublegetExpTree(Node root) {if (root == null) {return 0;

}if (root.leftChild == null && root.rightChild == null) {//叶节点,节点存放的是 操作数

return root.data - '0'; //将字符转换成数字

}//非叶结点,节点存放的是 操作符

double a =getExpTree(root.leftChild);double b =getExpTree(root.rightChild);returncal(a, b, root.data);

}public static double cal(double a, double b, charop) {switch(op) {case '+':return a +b;case '-':return a -b;case '*':return a *b;case '/':return a /b;default:return 0;

}

}public static voidmain(String[] args) {

Scanner input= newScanner(System.in);

System.out.println("请输入节点的个数");int N =input.nextInt();

Node[] nodes= newNode[N];for (int i = 0; i < N; i++) {

nodes[i]= newNode();

}

System.out.println("请输入index,data,l,r");for (int i = 0; i < N; i++) {int index =input.nextInt();char data = input.next().charAt(0);int l =input.nextInt();int r =input.nextInt();

nodes[index].data=data;

nodes[index].leftChild= (l != -1 ? nodes[l] : null);

nodes[index].rightChild= (r != -1 ? nodes[r] : null);

}

Node root= nodes[0];

inOrder(root,0);

System.out.println();

preOrder(root);

System.out.println();

postOrder(root);

System.out.println();double value =getExpTree(root);

System.out.println(value);

}

}

1bf43b5d53990244537482bc3f1014ad.png

2.7求二叉树指定节点所在层数(假设根节点的层数为1)

254d58787eb5a51a4e043adc7dce2676.png

1.方法1

packagedatastruct.t04tree.layer;classNode {intdata;

Node leftChild;

Node rightChild;public Node(intdata) {this.data =data;

}public voidsetChild(Node leftChild, Node rightChild) {this.leftChild =leftChild;this.rightChild =rightChild;

}

}public classNodeLayer {static int layer = 0;static boolean flag = false;//flag标记可用于提前快速结束递归的执行

public static void getNodeLayer(Node root, intvalue) {if (root == null)return;if(flag)return;

layer++;if (root.data ==value) {

System.out.println(layer);

flag= true;return;

}

getNodeLayer(root.leftChild, value);

getNodeLayer(root.rightChild, value);

layer--;

}public static voidmain(String[] args) {

Node root= new Node(1);

Node node2= new Node(2);

Node node3= new Node(3);

Node node4= new Node(4);

Node node5= new Node(5);

Node node6= new Node(6);

Node node7= new Node(7);

Node node8= new Node(8);

root.setChild(node2, node3);

node2.setChild(node4, node5);

node3.setChild(null, node6);

node5.setChild(node7,null);

node7.setChild(null, node8);int value = 7;

getNodeLayer(root, value);

}

}

2d1df325d46999d712a3f7ebaf9acda9.png

2.方法2

packagedatastruct.t04tree.layer;classNode {intdata;

Node leftChild;

Node rightChild;public Node(intdata) {this.data =data;

}public voidsetChild(Node leftChild, Node rightChild) {this.leftChild =leftChild;this.rightChild =rightChild;

}

}public classNodeLayer {

static boolean flag = false;public static void getNodeLayer(Node root, int value, intlayer) {if (root == null)return;if(flag)return;if (root.data ==value) {

System.out.println(layer);

flag= true;return;

}

getNodeLayer(root.leftChild, value, layer+ 1);

getNodeLayer(root.rightChild, value, layer+ 1);

}public static voidmain(String[] args) {

Node root= new Node(1);

Node node2= new Node(2);

Node node3= new Node(3);

Node node4= new Node(4);

Node node5= new Node(5);

Node node6= new Node(6);

Node node7= new Node(7);

Node node8= new Node(8);

root.setChild(node2, node3);

node2.setChild(node4, node5);

node3.setChild(null, node6);

node5.setChild(node7,null);

node7.setChild(null, node8);int value = 7;

getNodeLayer(root, value, 1);

}

}

271919a1022228b574696bcd739bdd7f.png

2.8求某节点到根节点的路径

对于如下二叉树,节点 7 位于第 4 层,其到跟节点的路径为 1 2 5 7

5d06ba42ad2b715bc6f4262de870485b.png

packagedatastruct.t04tree.path;importjava.util.Stack;classNode {intdata;

Node leftChild;

Node rightChild;public Node(intdata) {this.data =data;

}public voidsetChild(Node leftChild, Node rightChild) {this.leftChild =leftChild;this.rightChild =rightChild;

}

}public classTreePath {static Stack path = new Stack<>();static boolean flag = false;public static void getNodePath(Node root, intvalue) {if (root == null)return;if(flag)return;

path.add(root.data);if (root.data ==value) {for(Integer integer : path) {

System.out.print(integer+ " ");

}

flag= true;return;

}

getNodePath(root.leftChild, value);

getNodePath(root.rightChild, value);

path.pop();

}public static voidmain(String[] args) {

Node root= new Node(1);

Node node2= new Node(2);

Node node3= new Node(3);

Node node4= new Node(4);

Node node5= new Node(5);

Node node6= new Node(6);

Node node7= new Node(7);

Node node8= new Node(8);

root.setChild(node2, node3);

node2.setChild(node4, node5);

node3.setChild(null, node6);

node5.setChild(node7,null);

node7.setChild(null, node8);int value = 7;

getNodePath(root, value);

}

}

17cc859f015137378ebc034eb73fdf13.png

2.9全排列问题

输出数字1~N所能组成的所有全排列

c1555c02ef1650b93dee7637a020f719.png

packagedatastruct.t04tree.permutation;importjava.util.Stack;public classPermutation {public static int MAXN = 10;static boolean[] isUsed = new boolean[MAXN];static Stack nums = new Stack<>();static intN;/***@paramindex

* 表示第几层*/

public static void DFS(intindex) {if (index >=N) {for(Integer i : nums)

System.out.print(i+ " ");

System.out.println();return;

}for (int i = 1; i <= N; i++) {if(isUsed[i])continue;

nums.push(i);

isUsed[i]= true;

DFS(index+ 1);

nums.pop();

isUsed[i]= false;

}

}public static voidmain(String[] args) {

N= 3;

DFS(0);//从第0层开始搜索

}

}

1891fea9c566be57411d9e8731ffc0c3.png

3.红黑树

f812ea73e6b26004e314bb403fbb522f.png

9fde6ce1f7ba19b9c79d930db144b142.png

4.hash表

5526f563d2e3d2aaca4d8754712f82c2.png

4.1直接将关键字作为索引

packagech15;public classInfo {private intkey;privateString name;public Info(intkey, String name) {//TODO Auto-generated constructor stub

this.key =key;this.name =name;

}public intgetKey() {returnkey;

}public void setKey(intkey) {this.key =key;

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}

}

packagech15;public classHashTable {privateInfo[] arr;publicHashTable() {//TODO Auto-generated constructor stub

arr = new Info[100];

}public HashTable(intmaxSize) {

arr= newInfo[maxSize];

}public voidinsert(Info info) {

arr[info.getKey()]=info;

}public Info find(intkey) {returnarr[key];

}

}

packagech15;public classTestHashTable {public static voidmain(String[] args) {

HashTable hTable= newHashTable();

hTable.insert(new Info(10, "张三"));

hTable.insert(new Info(15, "李四"));

System.out.println(hTable.find(15).getName());

}

}

974f747312a20e2c75fbabe23bdae5f0.png

4.2将单词转化为索引

packagech15;public classInfo {privateString key;privateString name;publicInfo(String key, String name) {//TODO Auto-generated constructor stub

this.key =key;this.name =name;

}publicString getKey() {returnkey;

}public voidsetKey(String key) {this.key =key;

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}

}

packagech15;public classHashTable {privateInfo[] arr;publicHashTable() {//TODO Auto-generated constructor stub

arr = new Info[100];

}public HashTable(intmaxSize) {

arr= newInfo[maxSize];

}public voidinsert(Info info) {

arr[hashCode(info.getKey())]=info;

}publicInfo find(String key) {returnarr[hashCode(key)];

}public inthashCode(String key) {int hashValue = 0;for (int i = key.length() - 1; i >= 0; i--) {int letter = key.charAt(i) - 96;

hashValue+=letter;

}returnhashValue;

}

}

packagech15;public classTestHashTable {public static voidmain(String[] args) {

HashTable hTable= newHashTable();

hTable.insert(new Info("zhangsan", "张三"));

hTable.insert(new Info("lisi", "李四"));

System.out.println(hTable.find("zhangsan").getName());

}

}

eade14c5a5e3b21accbe9e938d3cb2e5.png

以上方法也会存在一定的问题,当hashcode相同的时候。

packagech15;public classTestHashTable {public static voidmain(String[] args) {

HashTable hTable= newHashTable();

hTable.insert(new Info("abc", "张三"));

hTable.insert(new Info("bca", "李四"));

System.out.println(hTable.find("abc").getName());

System.out.println(hTable.find("bca").getName());

}

}

b1d0f5ea0637f86fd9a62854e9307a84.png

我们用幂函数的方式去重写hashcode

public inthashCode(String key) {int hashValue = 0;int pow27 = 1;for (int i = key.length() - 1; i >= 0; i--) {int letter = key.charAt(i) - 96;

hashValue+= letter *pow27;

pow27*= 27;

}returnhashValue;

}

packagech15;public classTestHashTable {public static voidmain(String[] args) {

HashTable hTable= newHashTable();

hTable.insert(new Info("abc", "张三"));

hTable.insert(new Info("bca", "李四"));

System.out.println(hTable.find("abc").getName());

System.out.println(hTable.find("bca").getName());

}

}

f7250689744b1e714493de9160791a67.png

此时可以解决上面的问题,但是浪费太多内存了,因为字符串如果很长,数组容易越界或者内存溢出,因此需要进行取模运算。

public inthashCode(String key) {

BigInteger hashValue= new BigInteger("0");

BigInteger pow27= new BigInteger("1");for (int i = key.length() - 1; i >= 0; i--) {int letter = key.charAt(i) - 96;

BigInteger letterB= newBigInteger(String.valueOf(letter));

hashValue=hashValue.add(letterB.multiply(pow27));

pow27= pow27.multiply(new BigInteger(String.valueOf(27)));

}return hashValue.mod(newBigInteger(String.valueOf(key.length()))).intValue();

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.1 单项选择题 1. 数据结构是一门研究非数值计算的程序设计问题中,数据元素的① 、数据信息在计算机中的② 以及一组相关的运算等的课程。 ① A.操作对象   B.计算方法  C.逻辑结构  D.数据映象 ② A.存储结构 B.关系 C.运算 D.算法 2. 数据结构DS(Data Struct)可以被形式地定义为DS=(D,R),其中D是① 的有限集合,R是D上的② 有限集合。 ① A.算法 B.数据元素 C.数据操作 D.数据对象 ② A.操作 B.映象 C.存储 D.关系 3. 在数据结构中,从逻辑上可以把数据结构分成 。 A.动态结构和静态结构 B.紧凑结构和非紧凑结构 C.线性结构和非线性结构 D.内部结构和外部结构 4. 算法分析的目的是① ,算法分析的两个主要方面是② 。 ① A. 找出数据结构的合理性 B. 研究算法中的输入和输出的关系 C. 分析算法的效率以求改进 D. 分析算法的易懂性和文档性 ② A. 空间复杂性和时间复杂性 B. 正确性和简明性 C. 可读性和文档性 D. 数据复杂性和程序复杂性 5. 计算机算法指的是① ,它必具备输入、输出和② 等五个特性。 ① A. 计算方法 B. 排序方法 C. 解决问题的有限运算序列 D. 调度方法 ② A. 可行性、可移植性和可扩充性 B. 可行性、确定性和有穷性 C. 确定性、有穷性和稳定性 D. 易读性、稳定性和安全性 1.2 填空题(将正确的答案填在相应的空中) 1. 数据逻辑结构包括 、 、 和 四种类型,树形结构和图形结构合称为 。 2. 在线性结构中,第一个结点 前驱结点,其余每个结点有且只有 个前驱结点;最后一个结点 后续结点,其余每个结点有且只有 个后续结点。 3. 在树形结构中,树根结点没有 结点,其余每个结点有且只有 个直接前驱结点,叶子结点没有 结点,其余每个结点的直接后续结点可以 。 4. 在图形结构中,每个结点的前驱结点数和后续结点数可以 。 5. 线性结构中元素之间存在 关系,树形结构中元素之间存在 关系,图形结构中元素之间存在 关系。 6. 算法的五个重要特性是__ __ , __ __ , ___ _ , __ __ , _ ___。 7. 分析下面算法(程序段),给出最大语句频度 ,该算法的时间复杂度是__ __。 for (i=0;i<n;i++) for (j=0;j<n; j++) A[i][j]=0; 8. 分析下面算法(程序段),给出最大语句频度 ,该算法的时间复杂度是__ __。 for (i=0;i<n;i++) for (j=0; j<i; j++) A[i][j]=0; 9. 分析下面算法(程序段),给出最大语句频度 ,该算法的时间复杂度是__ __。 s=0; for (i=0;i<n;i++) for (j=0;j<n;j++) for (k=0;k<n;k++) s=s+B[i][j][k]; sum=s; 10. 分析下面算法(程序段)给出最大语句频度 ,该算法的时间复杂度是__ __。 int i=0,s=0; while (s<n) { i++; s+=i; //s=s+i } 11. 分析下面算法(程序段)给出最大语句频度 ,该算法的时间复杂度是__ __。 i=1; while (i<=n) i=i*2;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值