Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
GreyZeng
algorithm
提交
5c1d48b2
A
algorithm
项目概览
GreyZeng
/
algorithm
通知
10
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
algorithm
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5c1d48b2
编写于
11月 28, 2022
作者:
GreyZeng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update heap code
上级
e3d0e704
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
207 addition
and
222 deletion
+207
-222
src/main/java/snippet/Code_0026_Heap.java
src/main/java/snippet/Code_0026_Heap.java
+0
-220
src/main/java/snippet/Code_DistanceLessK.java
src/main/java/snippet/Code_DistanceLessK.java
+1
-1
src/main/java/snippet/Code_Heap.java
src/main/java/snippet/Code_Heap.java
+205
-0
src/main/java/snippet/Code_HeapSort.java
src/main/java/snippet/Code_HeapSort.java
+1
-1
未找到文件。
src/main/java/snippet/Code_0026_Heap.java
已删除
100644 → 0
浏览文件 @
e3d0e704
package
snippet
;
import
java.util.Comparator
;
import
java.util.PriorityQueue
;
/**
* 什么是完全二叉树
* 如果一个树是满的,它是完全二叉树,即便不是满的,也是从左到右依次变满的
* <p>
* 堆结构
* <p>
* 1)堆结构就是用数组实现的完全二叉树结构
* <p>
* 2)完全二叉树中如果每棵子树的最大值都在顶部就是大根堆
* <p>
* 3)完全二叉树中如果每棵子树的最小值都在顶部就是小根堆
* <p>
* 4)堆结构的heapInsert与heapify操作
* <p>
* 5)堆结构的增大和减少
* <p>
* 6)Java中的PriorityQueue,就是堆结构
* <p>
* 用数组表示堆的两种情况
* <p>
* 如果使用数组0位置,对于i位置来说,它的:
* <p>
* 左孩子 2 * i + 1
* <p>
* 右孩子 2 * i + 2
* <p>
* 父节点 (i - 1)/ 2
* <p>
* 如果不用0位置,对于i位置来说,它的:
* <p>
* 左孩子 2 * i 即:i << 1
* <p>
* 右孩子 2 * i + 1 即:i << 1 | 1
* <p>
* 父节点 i / 2 即:i >> 1
* <p>
* 大根堆:完全二叉树中,每棵树的最大值都是头节点的值
*
* heapify和heapInsert都是logN级别的复杂度,因为N个节点的二叉树高度是logN
*/
public
class
Code_0026_Heap
{
public
static
class
MyMaxHeap
{
private
int
[]
heap
;
private
final
int
limit
;
private
int
heapSize
;
public
MyMaxHeap
(
int
limit
)
{
heap
=
new
int
[
limit
];
this
.
limit
=
limit
;
heapSize
=
0
;
}
public
boolean
isEmpty
()
{
return
heapSize
==
0
;
}
public
boolean
isFull
()
{
return
heapSize
==
limit
;
}
public
void
push
(
int
value
)
{
if
(
heapSize
==
limit
)
{
throw
new
RuntimeException
(
"heap is full"
);
}
heap
[
heapSize
]
=
value
;
// value heapSize
heapInsert
(
heap
,
heapSize
++);
}
public
int
pop
()
{
int
ans
=
heap
[
0
];
swap
(
heap
,
0
,
--
heapSize
);
heapify
(
heap
,
0
,
heapSize
);
return
ans
;
}
private
void
heapInsert
(
int
[]
arr
,
int
index
)
{
while
(
arr
[
index
]
>
arr
[(
index
-
1
)
/
2
])
{
swap
(
arr
,
index
,
(
index
-
1
)
/
2
);
index
=
(
index
-
1
)
/
2
;
}
}
private
void
heapify
(
int
[]
arr
,
int
index
,
int
heapSize
)
{
int
left
=
index
*
2
+
1
;
while
(
left
<
heapSize
)
{
int
largest
=
left
+
1
<
heapSize
&&
arr
[
left
+
1
]
>
arr
[
left
]
?
left
+
1
:
left
;
largest
=
arr
[
largest
]
>
arr
[
index
]
?
largest
:
index
;
if
(
largest
==
index
)
{
break
;
}
swap
(
arr
,
largest
,
index
);
index
=
largest
;
left
=
index
*
2
+
1
;
}
}
private
void
swap
(
int
[]
arr
,
int
i
,
int
j
)
{
int
tmp
=
arr
[
i
];
arr
[
i
]
=
arr
[
j
];
arr
[
j
]
=
tmp
;
}
}
public
static
class
RightMaxHeap
{
private
int
[]
arr
;
private
final
int
limit
;
private
int
size
;
public
RightMaxHeap
(
int
limit
)
{
arr
=
new
int
[
limit
];
this
.
limit
=
limit
;
size
=
0
;
}
public
boolean
isEmpty
()
{
return
size
==
0
;
}
public
boolean
isFull
()
{
return
size
==
limit
;
}
public
void
push
(
int
value
)
{
if
(
size
==
limit
)
{
throw
new
RuntimeException
(
"heap is full"
);
}
arr
[
size
++]
=
value
;
}
public
int
pop
()
{
int
maxIndex
=
0
;
for
(
int
i
=
1
;
i
<
size
;
i
++)
{
if
(
arr
[
i
]
>
arr
[
maxIndex
])
{
maxIndex
=
i
;
}
}
int
ans
=
arr
[
maxIndex
];
arr
[
maxIndex
]
=
arr
[--
size
];
return
ans
;
}
}
public
static
class
MyComparator
implements
Comparator
<
Integer
>
{
@Override
public
int
compare
(
Integer
o1
,
Integer
o2
)
{
return
o2
-
o1
;
}
}
public
static
void
main
(
String
[]
args
)
{
// 小根堆
PriorityQueue
<
Integer
>
heap
=
new
PriorityQueue
<>(
new
MyComparator
());
heap
.
add
(
5
);
heap
.
add
(
5
);
heap
.
add
(
5
);
heap
.
add
(
3
);
// 5 , 3
System
.
out
.
println
(
heap
.
peek
());
heap
.
add
(
7
);
heap
.
add
(
0
);
heap
.
add
(
7
);
heap
.
add
(
0
);
heap
.
add
(
7
);
heap
.
add
(
0
);
System
.
out
.
println
(
heap
.
peek
());
while
(!
heap
.
isEmpty
())
{
System
.
out
.
println
(
heap
.
poll
());
}
int
value
=
1000
;
int
limit
=
100
;
int
testTimes
=
1000000
;
for
(
int
i
=
0
;
i
<
testTimes
;
i
++)
{
int
curLimit
=
(
int
)
(
Math
.
random
()
*
limit
)
+
1
;
MyMaxHeap
my
=
new
MyMaxHeap
(
curLimit
);
RightMaxHeap
test
=
new
RightMaxHeap
(
curLimit
);
int
curOpTimes
=
(
int
)
(
Math
.
random
()
*
limit
);
for
(
int
j
=
0
;
j
<
curOpTimes
;
j
++)
{
if
(
my
.
isEmpty
()
!=
test
.
isEmpty
())
{
System
.
out
.
println
(
"Oops!"
);
}
if
(
my
.
isFull
()
!=
test
.
isFull
())
{
System
.
out
.
println
(
"Oops!"
);
}
if
(
my
.
isEmpty
())
{
int
curValue
=
(
int
)
(
Math
.
random
()
*
value
);
my
.
push
(
curValue
);
test
.
push
(
curValue
);
}
else
if
(
my
.
isFull
())
{
if
(
my
.
pop
()
!=
test
.
pop
())
{
System
.
out
.
println
(
"Oops!"
);
}
}
else
{
if
(
Math
.
random
()
<
0.5
)
{
int
curValue
=
(
int
)
(
Math
.
random
()
*
value
);
my
.
push
(
curValue
);
test
.
push
(
curValue
);
}
else
{
if
(
my
.
pop
()
!=
test
.
pop
())
{
System
.
out
.
println
(
"Oops!"
);
}
}
}
}
}
System
.
out
.
println
(
"finish!"
);
}
}
\ No newline at end of file
src/main/java/snippet/Code_
0028_
DistanceLessK.java
→
src/main/java/snippet/Code_DistanceLessK.java
浏览文件 @
5c1d48b2
...
...
@@ -14,7 +14,7 @@ import java.util.PriorityQueue;
* 加k个数进堆,然后再加入一个,弹出一个,最后堆里面剩下的继续弹出即可
* 时间复杂度:O(N*logK)
*/
public
class
Code_
0028_
DistanceLessK
{
public
class
Code_DistanceLessK
{
public
static
void
sortedArrDistanceLessK
(
int
[]
arr
,
int
k
)
{
k
=
Math
.
min
(
arr
.
length
-
1
,
k
);
PriorityQueue
<
Integer
>
heap
=
new
PriorityQueue
<>();
...
...
src/main/java/snippet/Code_Heap.java
0 → 100644
浏览文件 @
5c1d48b2
package
snippet
;
import
java.util.PriorityQueue
;
/**
* 笔记: 什么是完全二叉树 如果一个树是满的,它是完全二叉树,即便不是满的,也是从左到右依次变满的
*
* <p>堆结构
*
* <p>1)堆结构就是用数组实现的完全二叉树结构
*
* <p>2)完全二叉树中如果每棵子树的最大值都在顶部就是大根堆
*
* <p>3)完全二叉树中如果每棵子树的最小值都在顶部就是小根堆
*
* <p>4)堆结构的heapInsert与heapify操作
*
* <p>5)堆结构的增大和减少
*
* <p>6)Java中的PriorityQueue,就是堆结构
*
* <p>用数组表示堆的两种情况
*
* <p>如果使用数组0位置,对于i位置来说,它的:
*
* <p>左孩子 2 * i + 1
*
* <p>右孩子 2 * i + 2
*
* <p>父节点 (i - 1)/ 2
*
* <p>如果不用0位置,对于i位置来说,它的:
*
* <p>左孩子 2 * i 即:i << 1
*
* <p>右孩子 2 * i + 1 即:i << 1 | 1
*
* <p>父节点 i / 2 即:i >> 1
*
* <p>大根堆:完全二叉树中,每棵树的最大值都是头节点的值
*
* <p>heapify和heapInsert都是logN级别的复杂度,因为N个节点的二叉树高度是logN
*/
public
class
Code_Heap
{
public
static
class
MyMaxHeap
{
private
int
[]
heap
;
private
final
int
limit
;
private
int
heapSize
;
public
MyMaxHeap
(
int
limit
)
{
heap
=
new
int
[
limit
];
this
.
limit
=
limit
;
heapSize
=
0
;
}
public
boolean
isEmpty
()
{
return
heapSize
==
0
;
}
public
boolean
isFull
()
{
return
heapSize
==
limit
;
}
public
void
push
(
int
value
)
{
if
(
heapSize
==
limit
)
{
throw
new
RuntimeException
(
"heap is full"
);
}
heap
[
heapSize
]
=
value
;
// value heapSize
heapInsert
(
heap
,
heapSize
++);
}
public
int
pop
()
{
int
ans
=
heap
[
0
];
swap
(
heap
,
0
,
--
heapSize
);
heapify
(
heap
,
0
,
heapSize
);
return
ans
;
}
private
void
heapInsert
(
int
[]
arr
,
int
index
)
{
while
(
arr
[
index
]
>
arr
[(
index
-
1
)
/
2
])
{
swap
(
arr
,
index
,
(
index
-
1
)
/
2
);
index
=
(
index
-
1
)
/
2
;
}
}
private
void
heapify
(
int
[]
arr
,
int
index
,
int
heapSize
)
{
int
left
=
index
*
2
+
1
;
while
(
left
<
heapSize
)
{
int
largest
=
left
+
1
<
heapSize
&&
arr
[
left
+
1
]
>
arr
[
left
]
?
left
+
1
:
left
;
largest
=
arr
[
largest
]
>
arr
[
index
]
?
largest
:
index
;
if
(
largest
==
index
)
{
break
;
}
swap
(
arr
,
largest
,
index
);
index
=
largest
;
left
=
index
*
2
+
1
;
}
}
private
void
swap
(
int
[]
arr
,
int
i
,
int
j
)
{
int
tmp
=
arr
[
i
];
arr
[
i
]
=
arr
[
j
];
arr
[
j
]
=
tmp
;
}
}
public
static
class
RightMaxHeap
{
private
int
[]
arr
;
private
final
int
limit
;
private
int
size
;
public
RightMaxHeap
(
int
limit
)
{
arr
=
new
int
[
limit
];
this
.
limit
=
limit
;
size
=
0
;
}
public
boolean
isEmpty
()
{
return
size
==
0
;
}
public
boolean
isFull
()
{
return
size
==
limit
;
}
public
void
push
(
int
value
)
{
if
(
size
==
limit
)
{
throw
new
RuntimeException
(
"heap is full"
);
}
arr
[
size
++]
=
value
;
}
public
int
pop
()
{
int
maxIndex
=
0
;
for
(
int
i
=
1
;
i
<
size
;
i
++)
{
if
(
arr
[
i
]
>
arr
[
maxIndex
])
{
maxIndex
=
i
;
}
}
int
ans
=
arr
[
maxIndex
];
arr
[
maxIndex
]
=
arr
[--
size
];
return
ans
;
}
}
public
static
void
main
(
String
[]
args
)
{
// 小根堆
PriorityQueue
<
Integer
>
heap
=
new
PriorityQueue
<>((
o1
,
o2
)
->
o2
-
o1
);
heap
.
add
(
5
);
heap
.
add
(
5
);
heap
.
add
(
5
);
heap
.
add
(
3
);
// 5 , 3
System
.
out
.
println
(
heap
.
peek
());
heap
.
add
(
7
);
heap
.
add
(
0
);
heap
.
add
(
7
);
heap
.
add
(
0
);
heap
.
add
(
7
);
heap
.
add
(
0
);
System
.
out
.
println
(
heap
.
peek
());
while
(!
heap
.
isEmpty
())
{
System
.
out
.
println
(
heap
.
poll
());
}
int
value
=
1000
;
int
limit
=
100
;
int
testTimes
=
1000000
;
for
(
int
i
=
0
;
i
<
testTimes
;
i
++)
{
int
curLimit
=
(
int
)
(
Math
.
random
()
*
limit
)
+
1
;
MyMaxHeap
my
=
new
MyMaxHeap
(
curLimit
);
RightMaxHeap
test
=
new
RightMaxHeap
(
curLimit
);
int
curOpTimes
=
(
int
)
(
Math
.
random
()
*
limit
);
for
(
int
j
=
0
;
j
<
curOpTimes
;
j
++)
{
if
(
my
.
isEmpty
()
!=
test
.
isEmpty
())
{
System
.
out
.
println
(
"Oops!"
);
}
if
(
my
.
isFull
()
!=
test
.
isFull
())
{
System
.
out
.
println
(
"Oops!"
);
}
if
(
my
.
isEmpty
())
{
int
curValue
=
(
int
)
(
Math
.
random
()
*
value
);
my
.
push
(
curValue
);
test
.
push
(
curValue
);
}
else
if
(
my
.
isFull
())
{
if
(
my
.
pop
()
!=
test
.
pop
())
{
System
.
out
.
println
(
"Oops!"
);
}
}
else
{
if
(
Math
.
random
()
<
0.5
)
{
int
curValue
=
(
int
)
(
Math
.
random
()
*
value
);
my
.
push
(
curValue
);
test
.
push
(
curValue
);
}
else
{
if
(
my
.
pop
()
!=
test
.
pop
())
{
System
.
out
.
println
(
"Oops!"
);
}
}
}
}
}
System
.
out
.
println
(
"finish!"
);
}
}
src/main/java/snippet/Code_
0075_
HeapSort.java
→
src/main/java/snippet/Code_HeapSort.java
浏览文件 @
5c1d48b2
...
...
@@ -8,7 +8,7 @@ import java.util.PriorityQueue;
// b. 从下到上的方法,时间复杂度为O(N)
// 2. 把堆的最大值和堆末尾的值交换, 然后减少堆的大小之后,再去调整堆, 一直周而复始,时间复杂度为O(N*logN) 【扩两倍估算复杂度法】
// 3. 把堆的大小减小成0之后,排序完成
public
class
Code_
0075_
HeapSort
{
// 堆排序额外空间复杂度O(1)
public
class
Code_HeapSort
{
// 堆排序额外空间复杂度O(1)
public
static
void
heapSort
(
int
[]
arr
)
{
if
(
arr
==
null
||
arr
.
length
<
2
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录