java map用二叉树_【课堂笔记分享】linkedlist、二叉树、hashmap
LinkedList序列分先進先出FIFO,先進后出FILO
FIFO在Java中又叫Queue 隊列
FILO在Java中又叫Stack 棧
LinkedList 與 List接口與ArrayList一樣,LinkedList也實現了List接口,諸如add,remove,contains等等方法。 詳細使用,請參考 ArrayList 常用方法,在此不作贅述。
接下來要講的是LinkedList的一些特別的地方
雙向鏈表 - Deque除了實現了List接口外,LinkedList還實現了雙向鏈表結構Deque,可以很方便的在頭尾插入刪除數據
什么是鏈表結構: 與數組結構相比較,數組結構,就好像是電影院,每個位置都有標示,每個位置之間的間隔都是一樣的。 而鏈表就相當于佛珠,每個珠子,只連接前一個和后一個,不用關心除此之外的其他佛珠在哪里。
package collection;
import java.util.LinkedList;
import charactor.Hero;
public class TestCollection {
public static void main(String[] args) {
//LinkedList是一個雙向鏈表結構的list
LinkedList ll =new LinkedList();
//所以可以很方便的在頭部和尾部插入數據
//在最后插入新的英雄
ll.addLast(new Hero("hero1"));
ll.addLast(new Hero("hero2"));
ll.addLast(new Hero("hero3"));
System.out.println(ll);
//在最前面插入新的英雄
ll.addFirst(new Hero("heroX"));
System.out.println(ll);
//查看最前面的英雄
System.out.println(ll.getFirst());
//查看最后面的英雄
System.out.println(ll.getLast());
//查看不會導致英雄被刪除
System.out.println(ll);
//取出最前面的英雄
System.out.println(ll.removeFirst());
//取出最后面的英雄
System.out.println(ll.removeLast());
//取出會導致英雄被刪除
System.out.println(ll);
}
}
隊列 - QueueLinkedList 除了實現了List和Deque外,還實現了Queue接口(隊列)。
Queue是先進先出隊列 FIFO,常用方法:
offer在最后添加元素
poll取出第一個元素
peek 查看第一個元素
package collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import charactor.Hero;
public class TestCollection {
public static void main(String[] args) {
//和ArrayList一樣,LinkedList也實現了List接口
List ll =new LinkedList();
//所不同的是LinkedList還實現了Deque,進而又實現了Queue這個接口
//Queue代表FIFO 先進先出的隊列
Queue q= new LinkedList();
//加在隊列的最后面
System.out.print("初始化隊列:\t");
q.offer(new Hero("Hero1"));
q.offer(new Hero("Hero2"));
q.offer(new Hero("Hero3"));
q.offer(new Hero("Hero4"));
System.out.println(q);
System.out.print("把第一個元素取poll()出來:\t");
//取出第一個Hero,FIFO 先進先出
Hero h = q.poll();
System.out.println(h);
System.out.print("取出第一個元素之后的隊列:\t");
System.out.println(q);
//把第一個拿出來看一看,但是不取出來
h=q.peek();
System.out.print("查看peek()第一個元素:\t");
System.out.println(h);
System.out.print("查看并不會導致第一個元素被取出來:\t");
System.out.println(q);
}
}
使用LinkedList實現Stack棧與FIFO(先入先出的)隊列類似的一種數據結構是FILO先入后出棧Stack
根據接口Stack :
實現類:MyStack
public class MyStack implements Stack并向這個棧中,壓入5個英雄,接著彈出5個英雄
package collection;
import charactor.Hero;
public interface Stack {
//把英雄推入到最后位置
public void push(Hero h);
//把最后一個英雄取出來
public Hero pull();
//查看最后一個英雄
public Hero peek();
}
package collection;
import java.util.LinkedList;
import charactor.Hero;
public class MyStack implements Stack{
LinkedList heros = new LinkedList();
@Override
public void push(Hero h) {
heros.addLast(h);
}
@Override
public Hero pull() {
return heros.removeLast();
}
@Override
public Hero peek() {
return heros.getLast();
}
public static void main(String[] args) {
MyStack heroStack = new MyStack();
for (int i = 0; i < 5; i++) {
Hero h = new Hero("hero name " + i);
System.out.println("壓入 hero:" + h);
heroStack.push(h);
}
for (int i = 0; i < 5; i++) {
Hero h =heroStack.pull();
System.out.println("彈出 hero" + h);
}
}
}
二叉樹
二叉樹概念二叉樹由各種節點組成
二叉樹特點:每個節點都可以有左子節點,右子節點
每一個節點都有一個值
package collection;
public class Node {
// 左子節點
public Node leftNode;
// 右子節點
public Node rightNode;
// 值
public Object value;
}
二叉樹排序-插入數據假設通過二叉樹對如下10個隨機數進行排序
67,7,30,73,10,0,78,81,10,74
排序的第一個步驟是把數據插入到該二叉樹中
插入基本邏輯是,小、相同的放左邊,大的放右邊
1. 67 放在根節點
2. 7 比 67小,放在67的左節點
3. 30 比67 小,找到67的左節點7,30比7大,就放在7的右節點
4. 73 比67大, 放在67的右節點
5. 10 比 67小,找到67的左節點7,10比7大,找到7的右節點30,10比30小,放在30的左節點。
...
...9. 10比67小,找到67的左節點7,10比7大,找到7的右節點30,10比30小,找到30的左節點10,10和10一樣大,放在左邊
package collection;
public class Node {
// 左子節點
public Node leftNode;
// 右子節點
public Node rightNode;
// 值
public Object value;
// 插入 數據
public void add(Object v) {
// 如果當前節點沒有值,就把數據放在當前節點上
if (null == value)
value = v;
// 如果當前節點有值,就進行判斷,新增的值與當前值的大小關系
else {
// 新增的值,比當前值小或者相同
if ((Integer) v -((Integer)value) <= 0) {
if (null == leftNode)
leftNode = new Node();
leftNode.add(v);
}
// 新增的值,比當前值大
else {
if (null == rightNode)
rightNode = new Node();
rightNode.add(v);
}
}
}
public static void main(String[] args) {
int randoms[] = new int[] { 67, 7, 30, 73, 10, 0, 78, 81, 10, 74 };
Node roots = new Node();
for (int number : randoms) {
roots.add(number);
}
}
}
二叉樹排序-遍歷通過上一個步驟的插入行為,實際上,數據就已經排好序了。 接下來要做的是看,把這些已經排好序的數據,遍歷成我們常用的List或者數組的形式
二叉樹的遍歷分左序,中序,右序左序即: 中間的數遍歷后放在左邊
中序即: 中間的數遍歷后放在中間
右序即: 中間的數遍歷后放在右邊如圖所見,我們希望遍歷后的結果是從小到大的,所以應該采用中序遍歷
package collection;
import java.util.ArrayList;
import java.util.List;
public class Node {
// 左子節點
public Node leftNode;
// 右子節點
public Node rightNode;
// 值
public Object value;
// 插入 數據
public void add(Object v) {
// 如果當前節點沒有值,就把數據放在當前節點上
if (null == value)
value = v;
// 如果當前節點有值,就進行判斷,新增的值與當前值的大小關系
else {
// 新增的值,比當前值小或者相同
if ((Integer) v -((Integer)value) <= 0) {
if (null == leftNode)
leftNode = new Node();
leftNode.add(v);
}
// 新增的值,比當前值大
else {
if (null == rightNode)
rightNode = new Node();
rightNode.add(v);
}
}
}
// 中序遍歷所有的節點
public List values() {
List values = new ArrayList<>();
// 左節點的遍歷結果
if (null != leftNode)
values.addAll(leftNode.values());
// 當前節點
values.add(value);
// 右節點的遍歷結果
if (null != rightNode)
values.addAll(rightNode.values());
return values;
}
public static void main(String[] args) {
int randoms[] = new int[] { 67, 7, 30, 73, 10, 0, 78, 81, 10, 74 };
Node roots = new Node();
for (int number : randoms) {
roots.add(number);
}
System.out.println(roots.values());
}
}案例:英雄二叉樹
根據上面的學習和理解,設計一個Hero二叉樹,HeroNode.
可以向這個英雄二叉樹插入不同的Hero對象,并且按照Hero的血量倒排序。
隨機生成10個Hero對象,每個Hero對象都有不同的血量值,插入這個HeroNode后,把排序結果打印出來。Hero
package charactor;
public class Hero {
public String name;
public float hp;
public int damage;
public Hero() {
}
public Hero(String name) {
this.name = name;
}
public String toString() {
return String.format("[name:%s hp:%.0f]%n", name,hp);
}
}HeroNode
package collection;
import java.util.ArrayList;
import java.util.List;
import charactor.Hero;
public class HeroNode {
public HeroNode leftHero;
public HeroNode rightHero;
// 聲明為Hero類型
public Hero value;
public void add(Hero v) {
if (null == value)
value = v;
else {
// 如果新英雄血量,比本節點大,就放在左邊
if (v.hp > value.hp) {
if (null == leftHero)
leftHero = new HeroNode();
leftHero.add(v);
}
else {
if (null == rightHero)
rightHero = new HeroNode();
rightHero.add(v);
}
}
}
public List values() {
List values = new ArrayList<>();
if (null != leftHero)
values.addAll(leftHero.values());
values.add(value);
if (null != rightHero)
values.addAll(rightHero.values());
return values;
}
public static void main(String[] args) {
List hs = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Hero h = new Hero();
h.name = "hero " + i;
h.hp = (float) (Math.random() * 900 + 100); // 100-1000的隨機血量
hs.add(h);
}
System.out.println("初始化10個Hero");
System.out.println(hs);
HeroNode heroTree = new HeroNode();
for (Hero hero : hs) {
heroTree.add(hero);
}
System.out.println("根據血量倒排序后的Hero");
List treeSortedHeros = heroTree.values();
System.out.println(treeSortedHeros);
}
}創建4萬個隨機數,然后用分別用冒泡法,選擇法,二叉樹3種排序算法進行排序,比較哪種更快
package collection;
import java.util.Arrays;
import java.util.List;
public class SortCompare {
public static void main(String[] args) {
//初始化隨機數
int total = 40000;
System.out.println("初始化一個長度是"+total+"的隨機數字的數組");
int[] originalNumbers = new int[total];
for (int i = 0; i < originalNumbers.length; i++) {
originalNumbers[i] = (int)(Math.random()*total);
}
System.out.println("初始化完畢");
System.out.println("接下來分別用3種算法進行排序");
//從初始化了的隨機數組復制過來,以保證,每一種排序算法的目標數組,都是一樣的
int[] use4sort;
use4sort= Arrays.copyOf(originalNumbers, originalNumbers.length);
int[] sortedNumbersBySelection= performance(new SelectionSort(use4sort),"選擇法");
use4sort= Arrays.copyOf(originalNumbers, originalNumbers.length);
int[] sortedNumbersByBubbling=performance(new BubblingSort(use4sort),"冒泡法");
use4sort= Arrays.copyOf(originalNumbers, originalNumbers.length);
int[] sortedNumbersByTree=performance(new TreeSort(use4sort),"二叉樹");
System.out.println("查看排序結果,是否是不同的數組對象");
System.out.println(sortedNumbersBySelection);
System.out.println(sortedNumbersByBubbling);
System.out.println(sortedNumbersByTree);
System.out.println("查看排序結果,內容是否相同");
System.out.println("比較 選擇法 和 冒泡法 排序結果:");
System.out.println(Arrays.equals(sortedNumbersBySelection, sortedNumbersByBubbling));
System.out.println("比較 選擇法 和 二叉樹 排序結果:");
System.out.println(Arrays.equals(sortedNumbersBySelection, sortedNumbersByTree));
}
interface Sort{
void sort();
int[] values();
}
static class SelectionSort implements Sort{
int numbers[];
SelectionSort(int [] numbers){
this.numbers = numbers;
}
@Override
public void sort() {
for (int j = 0; j < numbers.length-1; j++) {
for (int i = j+1; i < numbers.length; i++) {
if(numbers[i]
int temp = numbers[j];
numbers[j] = numbers[i];
numbers[i] = temp;
}
}
}
}
@Override
public int[] values() {
// TODO Auto-generated method stub
return numbers;
}
}
static class BubblingSort implements Sort{
int numbers[];
BubblingSort(int [] numbers){
this.numbers = numbers;
}
@Override
public void sort() {
for (int j = 0; j < numbers.length; j++) {
for (int i = 0; i < numbers.length-j-1; i++) {
if(numbers[i]>numbers[i+1]){
int temp = numbers[i];
numbers[i] = numbers[i+1];
numbers[i+1] = temp;
}
}
}
}
@Override
public int[] values() {
// TODO Auto-generated method stub
return numbers;
}
}
static class TreeSort implements Sort{
int numbers[];
Node n;
TreeSort(int [] numbers){
n =new Node();
this.numbers = numbers;
}
@Override
public void sort() {
for (int i : numbers) {
n.add(i);
}
}
@Override
public int[] values() {
List list = n.values();
int sortedNumbers[] = new int[list.size()];
for (int i = 0; i < sortedNumbers.length; i++) {
sortedNumbers[i] = Integer.parseInt(list.get(i).toString());
}
return sortedNumbers;
}
}
private static int[] performance(Sort algorithm, String type) {
long start = System.currentTimeMillis();
algorithm.sort();
int sortedNumbers[] = algorithm.values();
long end = System.currentTimeMillis();
System.out.printf("%s排序,一共耗時 %d 毫秒%n",type,end-start);
return sortedNumbers;
}
}
HashMap
HashMap的鍵值對HashMap儲存數據的方式是—— 鍵值對
package collection;
import java.util.HashMap;
public class TestCollection {
public static void main(String[] args) {
HashMap dictionary = new HashMap<>();
dictionary.put("adc", "物理英雄");
dictionary.put("apc", "魔法英雄");
dictionary.put("t", "坦克");
System.out.println(dictionary.get("t"));
}
}
鍵不能重復,值可以重復對于HashMap而言,key是唯一的,不可以重復的。
所以,以相同的key 把不同的value插入到 Map中會導致舊元素被覆蓋,只留下最后插入的元素。
不過,同一個對象可以作為值插入到map中,只要對應的key不一樣
package collection;
import java.util.HashMap;
import charactor.Hero;
public class TestCollection {
public static void main(String[] args) {
HashMap heroMap = new HashMap();
heroMap.put("gareen", new Hero("gareen1"));
System.out.println(heroMap);
//key為gareen已經有value了,再以gareen作為key放入數據,會導致原英雄,被覆蓋
//不會增加新的元素到Map中
heroMap.put("gareen", new Hero("gareen2"));
System.out.println(heroMap);
//清空map
heroMap.clear();
Hero gareen = new Hero("gareen");
//同一個對象可以作為值插入到map中,只要對應的key不一樣
heroMap.put("hero1", gareen);
heroMap.put("hero2", gareen);
System.out.println(heroMap);
}
}查找內容性能比較
準備一個ArrayList其中存放3000000(三百萬個)Hero對象,其名稱是隨機的,格式是hero-[4位隨機數]
hero-3229
hero-6232
hero-9365
...
因為總數很大,所以幾乎每種都有重復,把名字叫做 hero-5555的所有對象找出來
要求使用兩種辦法來尋找
1. 不使用HashMap,直接使用for循環找出來,并統計花費的時間
2. 借助HashMap,找出結果,并統計花費的時間
package collection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import charactor.Hero;
public class TestCollection {
public static void main(String[] args) {
List hs =new ArrayList<>();
System.out.println("初始化開始");
for (int i = 0; i < 3000000; i++) {
Hero h = new Hero( "hero-" + random());
hs.add(h);
}
//名字作為key
//名字相同的hero,放在一個List中,作為value
HashMap> heroMap =new HashMap();
for (Hero h : hs) {
List list= heroMap.get( h.name);
if(list==null){
list = new ArrayList<>();
heroMap.put(h.name, list);
}
list.add(h);
}
System.out.println("初始化結束");
System.out.println("開始查找");
findByIteration(hs);
findByMap(heroMap);
}
private static List findByMap(HashMap> m) {
long start =System.currentTimeMillis();
List result= m.get("hero-5555");
long end =System.currentTimeMillis();
System.out.printf("通過map查找,一共找到%d個英雄,耗時%d 毫秒%n",result.size(),end-start);
return result;
}
private static List findByIteration (List hs) {
long start =System.currentTimeMillis();
List result =new ArrayList<>();
for (Hero h : hs) {
if(h.name.equals("hero-5555")){
result.add(h);
}
}
long end =System.currentTimeMillis();
System.out.printf("通過for查找,一共找到%d個英雄,耗時%d 毫秒%n", result.size(),end-start);
return result;
}
public static int random(){
return ((int)(Math.random()*9000)+1000);
}
}
感謝你看到這里,我是程序員麥冬,一個java開發從業者,深耕行業六年了,每天都會分享java相關技術文章或行業資訊
歡迎大家關注和轉發文章,后期還有福利贈送!
總結
以上是生活随笔為你收集整理的java map用二叉树_【课堂笔记分享】linkedlist、二叉树、hashmap的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用友u8服务器优化,用友U8v10.1运
- 下一篇: 使html表格可编辑状态,js+Html