我的算法学习之路--04学习数据结构的第一天

本文详细介绍了数据结构中的队列、栈、链表和二叉树的基本概念及其实现,包括循环队列、普通栈、单链表、双链表以及二叉树的遍历方法。通过具体代码展示了这些数据结构的插入、删除、判断和遍历操作。此外,还讨论了如何判断链表是否存在环以及二叉树的遍历方式。
摘要由CSDN通过智能技术生成

1.队列

队列就是一种先插入可以先取出的数据结构,排队系统就用到

普通队列实现

class MyQueue[T:ClassTag] (length_ :Int ){
  if(length_ < 0){
    throw new Exception("队列长度不小于0")
  }
  var arr:Array[T]= new Array[T](length_)
  var length:Int = length_
  var front:Int = -1
  var rear:Int = -1
  var default :Array[T]= new Array(1)
  //判断队列是否为空
  def isEmpty ():Boolean = {
    return front == rear ;
  }
   //判断队列是否为满
  def isFull():Boolean ={
    return rear == length - 1
  }
  //添加元素
  def enqueue(value: T) = {
    if(isFull())
      throw new Exception("队列满")
    rear += 1;
    arr(rear) = value
  }
  //取出元素
  def dequeue() :T = {
    if(isEmpty())
      throw new Exception("队列空")
    front += 1;
    var temp = arr(front)
    arr(front) = default(0)
    return temp
  }
  override def toString: String = {
    var str:String = ""
    arr.filter(a => a != default(0)).foreach(a => str += a)
    return str
  }
}

循环队列

class MyCycleQueue[T:ClassTag](length_ :Int ){
  if(length_ < 0){
    throw new Exception("队列长度不小于0")
  }

  var arr:Array[T]= new Array(length_)
  var length:Int = length_
  var front:Int = 0
  var rear:Int = 0
  var default :Array[T]= new Array[T](1)

  //判断队列是否为空
  def isEmpty ():Boolean = {
    return front == rear ;
  }
  //判断队列是否为满
  def isFull():Boolean ={
    if ((rear + 1 + length - front) % length == 0)
      println(s"rear = $rear front = $front")
    return (rear + 1 + length - front) % length == 0
  }
  //添加元素
  def enqueue(value: T) = {
    if(isFull())
      throw new Exception("队列满")
    arr(rear) = value
    rear = (rear + 1) % length;
  }
  //取出元素
  def dequeue() :T = {
    if(isEmpty())
      throw new Exception("队列空")
    var temp = arr(front)
    arr(front) = default(0)
    front = (front + 1) % length
    return temp
  }
  override def toString: String = {
    var str:String = ""
    arr.filter(a => a != default(0)).foreach(a => str += a)
    return str
  }
}

  private val queue:Queue[String] = Queue()
  queue.enqueue("d")//在队列尾部加一元素
  queue.enqueue("dssd")//在队列尾部加一元素
  queue.enqueue("1213")//在队列尾部加一元素

  queue.dequeue();//取出并返回d

2.栈

栈就是一种后插入可以先取出的数据结构,比如浏览器记录回退

栈的实现

class MyStack[T:ClassTag] (length_ : Int){
  var length:Int = length_
  var rear = -1;
  var arr :Array[T] = new Array[T](length)
  var default = new Array[T](1)
  //判断是否为空栈
  def isEmpty ():Boolean = {
    return -1 == rear ;
  }

  //判断栈是否已满
  def isFull():Boolean ={
    return rear == length - 1
  }
  //把元素压入栈
  def push(value: T) = {
    if(isFull())
      throw new Exception("栈满")
    rear += 1;
    arr(rear) = value
  }
  //把元素从栈中取出
  def pop():T = {
    if(isEmpty())
      throw new Exception("队列空")
    var temp = arr(rear)
    arr(rear) = default(0)
    rear -= 1;
    return temp
  }
  override def toString: String = {
    var str:String = ""
    arr.filter(a => a != default(0)).foreach(a => str += a)
    return str
  }
}
  var stack: MyStack[String] = MyStack();
  stack.push("dasdsa")//在栈中压入元素
  stack.push("absdba")
  println(stack.pop())//取出栈顶元素absdba

3.链表

链表就是一种线性的数据结构,下面是链表的实现

单链表节点的实现,多个节点在一起就是链表

class Node(var value:Any){
    var next:Node
}

双链表节点的实现

class Node(var value:Any){
    var next:Node
    var prev:Node
}

链表就是一种插入删除方便,随机访问不便的数据结构

如果链表中一个节点可以通过next再次到达,那么这个链表就有环。

 判断链表有没有环可以用快慢双指针单

  def hasCycle(head: Node): Boolean = {
        var inode :Node = head
        var jnode :Node = head
        if(head != null||head.next != null){
            jnode = head.next.next
        }else{
            return false
        }
        while(inode != jnode){
                if(inode != null)
                inode = inode.next
                else
                return false
                if(jnode != null && jnode.next != null)
                jnode = jnode.next
                else
                return false
            }
        }
                return true
    }

就是让一个慢指针速度为1,快指针速度为2。因为两个指针的速度差为1,所以如果有环,两个指针必定可以相遇(两指针每移动一次,距离会拉开一个位置,如果有环,肯定会相遇的),若没有环,快指针会走到结尾。

4.二叉树

二叉树就是由一群对象组成的树形数据结构,这一群对象每一个都是这样的

class TreeNode(value_:Any , left_:TreeNode ,right_ :TreeNode){
    var value:Any = value_
    var left:TreeNode = left_
    var right:TreeNode = right_

}

left属性,称为左子树

right属性,称为右子树

树还有三种遍历方式,分别叫前序遍历,中序遍历,和后序遍历,这个语言还不好表达,直接上代码!

递归前序遍历

def runall(node:TreeNode){
    if(node == null)
    return
    //写需要做的操作,比如输出,或者全部加一
    print(node.val)
    runall(node.left)
    runall(node.right
)

非递归前序遍历

def runall(node:NodeTree){
    var stack = Stack()
    stack.push(node)
    while(!stack.isEmpty){
        var subnode = stack.pop()
        //做遍历操作
        print(subnode.value)
        if(subnode.right != null){
            stack.push(subnode.right)
        }
        if(subnode.left != null){
            stack.push(subnode.left)
        }

    }

}

递归中序遍历

def runall(node:TreeNode){
    if(node == null)
    return
    runall(node.left)
    //写需要做的操作,比如输出,或者全部加一
    print(node.val)
    runall(node.right)
)

非递归后序遍历

//java
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        if(root == null) return res;
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode cur = stack.pop();
            res.add(cur.val);
            if(cur.left!=null) stack.push(cur.left);
            if(cur.right!=null) stack.push(cur.right);
        }
        Collections.reverse(res);
        return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没有名字。。。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值