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;
}
}