视频加载失败

数据结构

1853 字
9 分钟
数据结构

数据结构概述#

这里数据结构我们主要介绍常见的数据结构。

其实在java里每个常用的数据结构都有配套的方法可以掉用,但是在这里我不仅会把方法写出,也会用自己的代码去表示那些数据结构的实现

我们会依次介绍栈、队列、链表、树、图等数据结构

栈#

栈:先进后出,后进先出,一端开口

以前可以用java自带的stack类,现在推荐用ArrayDeque类。里面有push、pop、peek、isEmpty等方法实现栈的功能

下面是我基于数组实现的栈,给了一些基本的方法

package mydo_levelup.datastructures;
public class MyStack<E> {//用泛型
E [] stack=(E[]) new Object[10];
int top=-1;
int size=0;
public int showLength(){
return stack.length;
}
public int getTop() {
return top;
}
public void setTop(int top) {
this.top = top;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public MyStack(){}
public boolean add(E value){
if(size==stack.length){//数据越界扩容
E [] temp=(E[]) new Object[(int) (size*1.5)];
for(int i=0;i<stack.length;i++){//手动遍历做深拷贝
temp[i]=stack[i];
}
stack=temp;
}
stack[++top]=value;
size++;
return true;
}
public E pop(){//获取栈顶元素并删除
if(isEmpty()){
return null;
}
E temp=stack[top--];
size--;
return temp;
}
public E peek(){//仅获取栈顶元素
return stack[top];
}
public boolean isEmpty(){//判断是否为空
if(size==0){
return true;
}
return false;
}
public int search(E value){//查找元素
for(int i=0;i<size;i++){
if(stack[i]==value)return i+1;
}
return -1;
}
}

队列#

队列:先进先出,后进后出,后端进,叫进队;前端出,叫出队

java里用Queue接口,使用LinkedList类实现队列的功能

下面是我基于数组实现的队列,给了一些基本的方法

package mydo_levelup.datastructures;
public class MyQueue <E>{//队列,队尾入队,队头出队
E[] stack=(E[])new Object[10];
int top=0;
int end=-1;
int size=0;
public void showRealStack(){
for(int i=0;i<stack.length;i++){
System.out.print(stack[i]+" ");
}
}
public void showStack(){
for(int i=top;i<=end;i++){
System.out.print(stack[i]+" ");
}
}
public boolean add(E e){
if(size==stack.length){//越界扩容
E[] temp=(E[])new Object[(int)(size*1.5)];
System.arraycopy(stack,0,temp,0,size);
stack=temp;
}
if(end==stack.length-1&&size<stack.length){//尾指针过头,整体前移
for(int i=0;i<size;i++){
stack[i]=stack[i+top];
}
end=end-top;//指针也要同步前移
top=0;
}
stack[++end]=e;
size++;
return true;
}
public E peek(){
if(size==0){
return null;
}
return stack[top];
}
public E poll(){
if(size==0){
return null;
}
size--;
return stack[top++];
}
}

数组#

数组:查找快,删改慢

这个太过基础了,太底层了,没必要单独实现

链表#

链表:删改快,查找慢:以对象做节点,每个节点包含数据和下个节点的地址(实现方式,创建一个链表类,包含数据和下个节点地址两个基本元素,然后对象与对象连接起来)

java里用LinkedList类实现链表的功能

下面是我实现的链表,给了一些基本的方法

package mydo_levelup.datastructures;
public class MyLink <E>{
E value;
MyLink<E> next=null;
public MyLink(E value){
this.value=value;
}
public MyLink(){}
public boolean add(E e){
//第一个节点也要算进去
if(this.value==null){
this.value=e;
return true;
}else if(next==null){
this.next=new MyLink<E>(e);
return true;
}
else{
return next.add(e);
}
}
public int search(E e){
if(this.value.equals(e)){
return 0;
}
else return this.next.search(e)+1;
}
public boolean remove(int index){//删除第index的链表节点
MyLink<E> temp=this;
for(int i=1;i<index-1;i++){
if(temp.next==null){return false;}
temp=temp.next;
}
temp.next=temp.next.next;
return true;
}
public boolean change(int index,E e){//传递要改的节点的索引,和要改的值
MyLink<E> temp=this;
for(int i=1;i<=index;i++){
if(temp.next==null){return false;}
temp=temp.next;
}
temp.value=e;
return true;
}
public void showLink(){
MyLink<E> temp=this;
while(temp!=null){
System.out.print(temp.value+" ");
temp=temp.next;
}
System.out.println();
}
}

树#

介绍一个数据结构:树

树有许多节点,每个节点就是一个对象

1. 二叉树#

二叉树也有节点,每个节点也是一个对象

这个节点对象含有(父节点地址,值,左子节点地址,右子节点地址)

树的基础元素认识图
树的基础元素认识图

2,二叉查找树#

二叉查找树是一种特殊的二叉树,它的每个节点都有一个值,且满足以下性质:

  • 1,每个节点上最多有两个子节点
  • 2,左子树的所有节点的值都小于根节点的值
  • 3,右子树的所有节点的值都大于根节点的值

我做了添加,和中序遍历的实现

package mydo_levelup.datastructures;
public class MyTree <E extends Comparable<E>>{
MyTree father=null;
MyTree leftSon=null;
MyTree rightSon=null;
E value;
public MyTree(E value,MyTree father){
this.value=value;
this.father=father;
}
public MyTree() {}
public boolean add(E value){//递归实现二叉查找树的添加
if(this.value==null) {
this.value=value;
return true;
}
else if(this.value.compareTo(value)>0) {
if(this.leftSon==null) {
this.leftSon=new MyTree(value,this);
return true;
}else {
this.leftSon.add(value);
}
}else if(this.value.compareTo(value)<0) {
if(this.rightSon==null) {
this.rightSon=new MyTree(value,this);
return true;
}else {
this.rightSon.add(value);
}
}
return false;
}
public void show(){//递归实现中序遍历
MyTree temp=this;
if(temp.leftSon!=null) {
temp.leftSon.show();
}
System.out.print(this.value+" ");
if(temp.rightSon!=null) {
temp.rightSon.show();
}else {
return;
}
}
}

遍历方式#

1,前序遍历:先访问根节点,再访问左子树,最后访问右子树 2,中序遍历:先访问左子树,再访问根节点,最后访问右子树 3,后序遍历:先访问左子树,再访问右子树,最后访问根节点

3,二叉平衡树#

定义#

因为二叉查找树存在缺点:可能会让一边子树的层数过长,让整体的效率变低,所以出现了平衡二叉树

二叉平衡树是一种特殊的二叉查找树,它的每个节点的左子树和右子树的高度差至多为1。

左旋和右旋#

让二叉树保持平衡的方式有两种:左旋和右旋。

左旋步骤:

1,从添加的结点开始,往父节点找,当左右子树层数差大于1的节点作支点

2,把支点左旋降级,变成左子节点

3,支点的右子节点上升

4,若支点的右子节点上有左子节点,那就让这个左子节点连到降级后的支点的右子节点上。

右旋的步骤一致,只不过方向相反而已

特别的旋转应对#

下面这几种添加方式对应了不同的旋转操作

1,左左:在根节点左子树上的左子树上添加节点->作一次右旋

2,左右:在根节点左子树上的右子树上添加节点->先做局部左旋,再作整体右旋

3,右左:在根节点右子树上的左子树上添加节点->先做局部右旋,再作整体左旋

4,右右:在根节点右子树上的右子树上添加节点->作一次左旋

4,红黑树***#

定义#

是一种特殊的二叉查找树,它可以通过红黑规则来做一定的平衡。

它的节点对象上多了一个颜色属性

基本规则

① 每一个节点或是红色的,或者是黑色的

② 根节点必须是黑色

③ 如果一个节点没有子节点或者父节点,则该节点相应的指针属性值为 Nil,这些 Nil 视为叶节点,每个叶节点 (Nil) 是黑色的

④ 如果某一个节点是红色,那么它的子节点必须是黑色 (不能出现两个红色节点相连的情况)

⑤ 对每一个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点;

java里被用在TreeMap,HashMap等集合里。

插入节点#

我们总结上面的规则,做出来的应对不同添加情况所做的步骤如下

红黑树插入元素步骤图
红黑树插入元素步骤图

注意:对于添加节点非根,并且父节点是红色,叔叔节点是黑色的两种情况,(即图中绿色和灰色操作块的内容)这张图只展示了父节点在祖父节点左边的情况,其实还应该分类一个父亲节点在祖父节点右边的情况,步骤是一致的,只不过旋转方向反过来

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

数据结构
https://firefly.cuteleaf.cn/posts/datastructures/
作者
林言
发布于
2026-09-15
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
林言
嘟嘟哒嘟嘟哒
公告
欢迎来到我的博客!这是一则示例公告。
分类
标签
最新动态
站点统计
文章
11
分类
2
标签
2
总字数
27,534
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Cloudflare Pages
博客版本
Firefly v6.16.4
文章许可
CC BY-NC-SA 4.0